1. 程式人生 > >2016年4月CCF計算機軟體能力認證模擬試題程式碼參考

2016年4月CCF計算機軟體能力認證模擬試題程式碼參考

問題描述
給定n個正整數,找出它們中出現次數最多的數。如果這樣的數有多個,請輸出其中最小的一個。
輸入格式
輸入的第一行只有一個正整數n(1 ≤ n ≤ 1000),表示數字的個數。
輸入的第二行有n個整數s1, s2, …, sn (1 ≤ si ≤ 10000, 1 ≤ i ≤ n)。相鄰的數用空格分隔。
輸出格式
輸出這n個次數中出現次數最多的數。如果這樣的數有多個,輸出其中最小的一個。
樣例輸入
6
10 1 10 20 30 20
樣例輸出
10

隨便怎麼亂搞都行,直接陣列記數也行,和我一樣寫取尺法也行

#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <Stack>
#include <queue>
#include <cstdio>
#include <cctype>
#include <bitset>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
#define fuck(x) cout << "[" << x << "]"
#define FIN freopen("input.txt", "r", stdin)
#define FOUT freopen("output.txt", "w+", stdout)
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef vector<LL> vec;
typedef vector<vec> mat;

const int MX = 1e3 + 5;

int A[MX];
int main() {
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        scanf("%d", &A[i]);
    }
    sort(A + 1, A + 1 + n);
    int Max = 0, ans, l, r;
    for(l = 1; l <= n; l = r + 1) {
        for(r = l; r < n && A[l] == A[r + 1]; r++);
        int cnt = r - l + 1;
        if(cnt > Max || (cnt == Max && A[l] < ans)) {
            Max = cnt; ans = A[l];
        }
    }
    printf("%d\n", ans);
    return 0;
}
問題描述
每一本正式出版的圖書都有一個ISBN號碼與之對應,ISBN碼包括9位數字、1位識別碼和3位分隔符,其規定格式如“x-xxx-xxxxx-x”,其中符號“-”是分隔符(鍵盤上的減號),最後一位是識別碼,例如0-670-82162-4就是一個標準的ISBN碼。ISBN碼的首位數字表示書籍的出版語言,例如0代表英語;第一個分隔符“-”之後的三位數字代表出版社,例如670代表維京出版社;第二個分隔之後的五位數字代表該書在出版社的編號;最後一位為識別碼。
識別碼的計算方法如下:
首位數字乘以1加上次位數字乘以2……以此類推,用所得的結果mod 11,所得的餘數即為識別碼,如果餘數為10,則識別碼為大寫字母X。例如ISBN號碼0-670-82162-4中的識別碼4是這樣得到的:對067082162這9個數字,從左至右,分別乘以1,2,…,9,再求和,即0×1+6×2+……+2×9=158,然後取158 mod 11的結果4作為識別碼。
編寫程式判斷輸入的ISBN號碼中識別碼是否正確,如果正確,則僅輸出“Right”;如果錯誤,則輸出是正確的ISBN號碼。
輸入格式
輸入只有一行,是一個字元序列,表示一本書的ISBN號碼(保證輸入符合ISBN號碼的格式要求)。
輸出格式
輸出一行,假如輸入的ISBN號碼的識別碼正確,那麼輸出“Right”,否則,按照規定的格式,輸出正確的ISBN號碼(包括分隔符“-”)。
樣例輸入1
0-670-82162-4
樣例輸出1
Right
樣例輸入2
0-670-82162-0
樣例輸出2
0-670-82162-4
xjb亂搞
#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <Stack>
#include <queue>
#include <cstdio>
#include <cctype>
#include <bitset>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
#define fuck(x) cout << "[" << x << "]"
#define FIN freopen("input.txt", "r", stdin)
#define FOUT freopen("output.txt", "w+", stdout)
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef vector<LL> vec;
typedef vector<vec> mat;

const int MX = 1e3 + 5;

char S[MX];
int main() {
    scanf("%s", S);
    int sz = 0, n = strlen(S), s = 0;
    for(int i = 0; i < n - 1; i++) {
        if(S[i] != '-') {
            s += (S[i] - '0') * (++sz);
            s %= 11;
        }
    }

    bool sign;
    if(s == 10) {
        sign = (S[n - 1] == 'X');
    } else {
        sign = (S[n - 1] - '0' == s);
    }
    if(sign) printf("Right\n");
    else {
        char x = s == 10 ? 'X' : '0' + s;
        S[n - 1] = x;
        printf("%s\n", S);
    }
    return 0;
}


問題描述
在橫軸上放了n個相鄰的矩形,每個矩形的寬度是1,而第i(1 ≤ i ≤ n)個矩形的高度是hi。這n個矩形構成了一個直方圖。例如,下圖中六個矩形的高度就分別是3, 1, 6, 5, 2, 3。

請找出能放在給定直方圖裡面積最大的矩形,它的邊要與座標軸平行。對於上面給出的例子,最大矩形如下圖所示的陰影部分,面積是10。

輸入格式
第一行包含一個整數n,即矩形的數量(1 ≤ n ≤ 1000)。
第二行包含n 個整數h1, h2, … , hn,相鄰的數之間由空格分隔。(1 ≤ hi ≤ 10000)。hi是第i個矩形的高度。
輸出格式
輸出一行,包含一個整數,即給定直方圖內的最大矩形的面積。
樣例輸入
6
3 1 6 5 2 3
樣例輸出
10
資料範圍這麼小,連單調棧都不需要維護,兩個for迴圈就搞完了
#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <Stack>
#include <queue>
#include <cstdio>
#include <cctype>
#include <bitset>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
#define fuck(x) cout << "[" << x << "]"
#define FIN freopen("input.txt", "r", stdin)
#define FOUT freopen("output.txt", "w+", stdout)
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef vector<LL> vec;
typedef vector<vec> mat;

const int MX = 1e3 + 5;

int A[MX];
int main() {
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        scanf("%d", &A[i]);
    }

    int ans = 0;
    for(int i = 1; i <= n; i++) {
        int Min = A[i];
        for(int j = i; j <= n; j++) {
            Min = min(Min, A[j]);
            ans = max(ans, Min * (j - i + 1));
        }
    }
    printf("%d\n", ans);
    return 0;
}


問題描述
我們把一個數稱為有趣的,當且僅當:
1. 它的數字只包含0, 1, 2, 3,且這四個數字都出現過至少一次。
2. 所有的0都出現在所有的1之前,而所有的2都出現在所有的3之前。
3. 最高位數字不為0。
因此,符合我們定義的最小的有趣的數是2013。除此以外,4位的有趣的數還有兩個:2031和2301。
請計算恰好有n位的有趣的數的個數。由於答案可能非常大,只需要輸出答案除以1000000007的餘數。
輸入格式
輸入只有一行,包括恰好一個正整數n (4 ≤ n ≤ 1000)。
輸出格式
輸出只有一行,包括恰好n 位的整數中有趣的數的個數除以1000000007的餘數。
樣例輸入
4
樣例輸出
3
設dp[i][s]表示長度為i,數字的狀態為s時的種類數。

s直接狀態壓縮了一下,s>>i&1表示數字i是否以及出現過

接下來xjb數位dp就行了

#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <Stack>
#include <queue>
#include <cstdio>
#include <cctype>
#include <bitset>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
#define fuck(x) cout << "[" << x << "]"
#define FIN freopen("input.txt", "r", stdin)
#define FOUT freopen("output.txt", "w+", stdout)
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef vector<LL> vec;
typedef vector<vec> mat;

const int MX = 1e3 + 5;
const int mod = 1e9 + 7;

LL dp[MX][20];
int main() {
    int n;
    scanf("%d", &n);
    dp[1][2] = dp[1][4] = dp[1][8] = 1;
    for(int i = 2; i <= n; i++) {
        for(int s = 0; s < 16; s++) {
            for(int j = 0; j <= 3; j++) {
                if(j == 0 && (s >> 1 & 1)) continue;
                if(j == 2 && (s >> 3 & 1)) continue;
                int news = s | (1 << j);
                dp[i][news] += dp[i - 1][s];
                dp[i][news] %= mod;
            }
        }
    }
    printf("%lld\n", dp[n][15]);
    return 0;
}



問題描述
給定一個R行C列的地圖,地圖的每一個方格可能是'#', '+', '-', '|', '.', 'S', 'T'七個字元中的一個,分別表示如下意思:
'#': 任何時候玩家都不能移動到此方格;
'+': 當玩家到達這一方格後,下一步可以向上下左右四個方向相鄰的任意一個非'#'方格移動一格;
'-': 當玩家到達這一方格後,下一步可以向左右兩個方向相鄰的一個非'#'方格移動一格;
'|': 當玩家到達這一方格後,下一步可以向上下兩個方向相鄰的一個非'#'方格移動一格;
'.': 當玩家到達這一方格後,下一步只能向下移動一格。如果下面相鄰的方格為'#',則玩家不能再移動;
'S': 玩家的初始位置,地圖中只會有一個初始位置。玩家到達這一方格後,下一步可以向上下左右四個方向相鄰的任意一個非'#'方格移動一格;
'T': 玩家的目標位置,地圖中只會有一個目標位置。玩家到達這一方格後,可以選擇完成任務,也可以選擇不完成任務繼續移動。如果繼續移動下一步可以向上下左右四個方向相鄰的任意一個非'#'方格移動一格。
此外,玩家不能移動出地圖。
請找出滿足下面兩個性質的方格個數:
1. 玩家可以從初始位置移動到此方格;
2. 玩家不可以從此方格移動到目標位置。
輸入格式
輸入的第一行包括兩個整數R 和C,分別表示地圖的行和列數。(1 ≤ R, C ≤ 50)。
接下來的R行每行都包含C個字元。它們表示地圖的格子。地圖上恰好有一個'S'和一個'T'。
輸出格式
如果玩家在初始位置就已經不能到達終點了,就輸出“I'm stuck!”(不含雙引號)。否則的話,輸出滿足性質的方格的個數。
樣例輸入
5 5
--+-+
..|#.
..|##
S-+-T
####.
樣例輸出
2
樣例說明
如果把滿足性質的方格在地圖上用'X'標記出來的話,地圖如下所示:
--+-+
..|#X
..|##
S-+-T
####X
就這題噁心。

很明顯兩次加上方向的vis的BFS。但是要注意從起點和終點出發,裡面的判斷是有些不一樣的

#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <Stack>
#include <queue>
#include <cstdio>
#include <cctype>
#include <bitset>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
#define fuck(x) cout << "[" << x << "]"
#define FIN freopen("input.txt", "r", stdin)
#define FOUT freopen("output.txt", "w+", stdout)
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef vector<LL> vec;
typedef vector<vec> mat;

const int MX = 50 + 5;

int n, m;
bool vis[MX][MX][4];
bool sign[MX][MX][3];
char S[MX][MX];
struct Data {
    int x, y, d;
    Data() {}
    Data(int _x, int _y, int _d) {
        x = _x; y = _y; d = _d;
    }
} Begin, End;
int dist[][2] = {{0, 1}, {0, -1}, {1, 0}, { -1, 0}};//右左下上

void BFS_IN(Data bg) {
    queue<Data>Q;
    for(int i = 0; i < 4; i++) {
        Q.push(Data(bg.x, bg.y, i));
    }
    while(!Q.empty()) {
        Data fp = Q.front(); Q.pop();

        vis[fp.x][fp.y][fp.d] = 1;
        sign[fp.x][fp.y][0] = 1;
        for(int k = 0; k < 4; k++) {
            int nx = fp.x + dist[k][0];
            int ny = fp.y + dist[k][1];
            if(S[fp.x][fp.y] == '-' && k >= 2) continue;
            if(S[fp.x][fp.y] == '|' && k <= 1) continue;
            if(S[fp.x][fp.y] == '.' && k != 2) continue;
            if(nx < 1 || nx > n || ny < 1 || ny > m) continue;
            if(vis[nx][ny][k] || S[nx][ny] == '#') continue;

            vis[nx][ny][k] = 1;
            Q.push(Data(nx, ny, k));
        }
    }
}

void BFS_OUT(Data bg) {
    queue<Data>Q;
    for(int i = 0; i < 4; i++) {
        Q.push(Data(bg.x, bg.y, i));
    }
    while(!Q.empty()) {
        Data fp = Q.front(); Q.pop();

        vis[fp.x][fp.y][fp.d] = 1;
        sign[fp.x][fp.y][1] = 1;
        for(int k = 0; k < 4; k++) {
            int nx = fp.x + dist[k][0];
            int ny = fp.y + dist[k][1];
            if(nx < 1 || nx > n || ny < 1 || ny > m) continue;
            if(vis[nx][ny][k] || S[nx][ny] == '#') continue;
            if(S[nx][ny] == '-' && k >= 2) continue;
            if(S[nx][ny] == '|' && k <= 1) continue;
            if(S[nx][ny] == '.' && k != 3) continue;

            vis[nx][ny][k] = 1;
            Q.push(Data(nx, ny, k));
        }
    }
}

int main() {
    //FIN;
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++) {
        scanf("%s", S[i] + 1);
        for(int j = 1; j <= m; j++) {
            if(S[i][j] == 'S') Begin = Data(i, j, 0);
            if(S[i][j] == 'T') End = Data(i, j, 0);
        }
    }

    BFS_IN(Begin);
    memset(vis, 0, sizeof(vis));
    BFS_OUT(End);

    if(!sign[End.x][End.y][0]) printf("I'm stuck!\n");
    else {
        int ans = 0;
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                if(sign[i][j][0] && !sign[i][j][1]) ans++;
            }
        }
        printf("%d\n", ans);
    }

    /*for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= m; j++) {
            fuck((int)sign[i][j][1]);
        }
        printf("\n");
    }*/
    return 0;
}

總結:模擬題只是找自信的,考試還是要掛