2016年4月CCF計算機軟體能力認證模擬試題程式碼參考
阿新 • • 發佈:2019-01-03
問題描述
給定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; }
xjb亂搞問題描述 每一本正式出版的圖書都有一個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
#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;
}
總結:模擬題只是找自信的,考試還是要掛