2016 年實驗班選拔試題

  1. SUM(10 分)
    題目描述:求出在 1 到 N 之間的所有整數的總和。
    輸入格式:輸入包含多組測試數據。每行是一組測試數據,該數據是一個絕對值不
    大於 10000 的整數 N。N=0 時,表示輸入結束。
    輸出格式:對於每組測試數據,輸出一行,改行包含一個整數,是所有在 1 到 N 之
    間的整數的總和。
輸入樣例:
-3
0
輸出樣例:
-5 

求和公式

#include<bits/stdc++.h>

using namespace std;
int n;

int main() {
    while (scanf("%d", &n), n)
        printf("%d\n", (1 + n) * (abs(n - 1) + 1) / 2);
    return 0;
}
  1. Doubles(20 分)
    題目描述:給出 2 到 15 個不同的正整數,計算在這些數裏面有多少對數據滿足一個
    數是另一個數的兩倍。比如給出:
    1 4 3 2 9 7 18 22
    答案是 3。因爲 2 是 1 的兩倍,4 是 2 的兩倍,18 是 9 的兩倍。
    輸入格式:輸入包含多組測試數據。每組測試數據包括一行,給出 2 到 15 個兩兩不
    同且大於 0 小於 1000000 的正整數。每一行的最後一個數是 0,表示這一行的結束。輸
    入的最後一行只包括一個整數-1,這行表示輸入數據的結束,不用進行處理。
    輸出格式:對於每組測試數據,輸出一行,給出有多少個數對滿足其中一個數是另
    一個數的兩倍。
輸入樣例
1 4 3 2 9 7 18 22 0
2 4 8 10 0
7 5 11 13 1 3 0
-1
輸出樣例:
3
2
0 

由於數據規模較小,直接枚舉所有情況,複雜度爲O(n2)O(n^2)

#include<bits/stdc++.h>

using namespace std;
const int N = 20;
int a[N];

int main() {
    while (scanf("%d", &a[1]), a[1] != -1) {
        int n = 1;
        while (scanf("%d", &a[n + 1]), a[n + 1])n++;
        int cnt = 0;
        for (int i = 1; i < n; i++)
            for (int j = i + 1; j <= n; j++)
                if (a[i] == a[j] * 2 || a[i] * 2 == a[j])cnt++;
        printf("%d\n", cnt);
    }
    return 0;
}

假如數據規模達到了10610^6,可以對於每個數xx,找這個數之前等於2x2·xx/2x/2的個數求和即可,複雜度爲O(n)O(n)

#include<bits/stdc++.h>

using namespace std;
const int N = 1000010;
int a[N];
unordered_map<int, int> cnt;

int main() {
    while (scanf("%d", &a[1]), a[1] != -1) {
        int n = 1;
        while (scanf("%d", &a[n + 1]), a[n + 1])n++;
        long long ans = 0;
        cnt.clear();
        for (int i = 1; i <= n; i++) {
            ans += cnt[a[i] * 2];
            if (a[i] % 2 == 0)ans += cnt[a[i] / 2];
            cnt[a[i]]++;
        }
        printf("%lld\n", ans);
    }
    return 0;
}
  1. Count(30 分)
    題目描述:輸入一組單詞,輸出指定單詞的出現次數。
    輸入格式:輸入數據包含若干測試用例,每個測試用例的格式爲:第一行:N;第二
    行:N 個單詞,相鄰單詞用一個空格間隔;第三行:指定單詞。當讀到 N=0 時輸入結
    束。其中 N 不超過 1000,每個單詞長度不超過 10,僅字母大小寫有區別的單詞認爲是
    同一個單詞。
    輸出格式:對於每個測試用例,輸出指定單詞的出現次數。
輸入樣例:
3
ACM ICPC TEACHING 
ICPC
2
TEACHING research
ACM
5
Teaching ACM RESEARCH aCm Acm
ACM
0
輸出樣例:
1
0
3 

利用stl中的map統計個數即可。

#include<bits/stdc++.h>

using namespace std;
map<string, int> cnt;
int n;

int main() {
    while (scanf("%d", &n), n) {
        cnt.clear();
        string s;
        for (int i = 1; i <= n; i++) {
            cin >> s;
            int l = s.size();
            for (int j = 0; j < l; j++)if (s[j] >= 'A' && s[j] < 'Z')s[j] += 'a' - 'A';
            cnt[s]++;
        }
        cin >> s;
        int l = s.size();
        for (int j = 0; j < l; j++)if (s[j] >= 'A' && s[j] < 'Z')s[j] += 'a' - 'A';
        printf("%d\n", cnt[s]);
    }
    return 0;
}
  1. Error Correction(30 分)
    Description
    A boolean matrix has the parity property when each row and each column has an
    even sum, i.e. contains an even number of bits which are set. Here’s a 4 x 4 matrix which
    has the parity property:
1 0 1 0
0 0 0 0
1 1 1 1
0 1 0 1

The sums of the rows are 2, 0, 4 and 2. The sums of the columns are 2, 2, 2 and 2.
Your job is to write a program that reads in a matrix and checks if it has the parity
property. If not, your program should check if the parity property can be established by
changing only one bit. If this is not possible either, the matrix should be classified as
corrupt.
Input
The input will contain one or more test cases. The first line of each test case contains
one integer n (n<100), representing the size of the matrix. On the next n lines, there will
be n integers per line. No other integers than 0 and 1 will occur in the matrix. Input will
be terminated by a value of 0 for n.
Output
For each matrix in the input file, print one line. If the matrix already has the parity
property, print “OK”. If the parity property can be established by changing one bit, print
“Change bit (i,j)” where i is the row and j the column of the bit to be changed. Otherwise,
print “Corrupt”.

Sample Input
4
1 0 1 0
0 0 0 0
1 1 1 1
0 1 0 1
4 
1 0 1 0
0 0 1 0
1 1 1 1
0 1 0 1
4
1 0 1 0
0 1 1 0
1 1 1 1
0 1 0 1
0
Sample Output
OK
Change bit (2,3)
Corrupt 

統計各行各列的和,如果均爲偶數,則輸出"OK";如果僅有一個行ii和一個列jj和爲奇數,則輸出"Change bit (i,j)";其他情況輸出"Corrupt "。

#include<bits/stdc++.h>

using namespace std;
const int N = 105;
int row[N], col[N], n;

int main() {
    while (scanf("%d", &n), n) {
        for (int i = 1; i <= n; i++)row[i] = col[i] = 0;
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++) {
                int x;
                scanf("%d", &x);
                if (x)row[i]++, col[j]++;
            }
        bool suc = true;
        int x = 0, y = 0;
        for (int i = 1; i <= n; i++) {
            if (row[i] % 2) {
                if (x) {
                    suc = false;
                    break;
                }
                x = i;
            }
            if (col[i] % 2) {
                if (y) {
                    suc = false;
                    break;
                }
                y = i;
            }
        }
        if (!x && !y)puts("OK");
        else if (suc && x && y)printf("Change bit (%d,%d)\n", x, y);
        else puts("Corrupt");
    }
    return 0;
}
  1. 迴文詞(50 分)
    題目描述:迴文詞是一種對稱的字符串,即一個字符串從左向右讀和從右向左讀是
    等同的。任意給出一個字符串,通過插入若干個字符,都可以變成迴文詞。本題的任務
    是,求出將給定字符串變成迴文詞所需要插入的最少字符數。
    比如“Ab3bd”插入兩個字符後 可以變成迴文詞“dAb3bAd”或“Adb3bdA”,但是插入
    少於兩個的字符無法變成迴文詞。
    輸入格式:輸入數據由多組測試用例組成。每組測試用例包含兩行輸入,第一行是
    一個整數,表示輸入的字符串長度 N,3<=N<=5000;第二行給出長度爲 N 的字符串。
    字符串由 A 到 Z 的大寫字母,a 到 z 的小寫字母和從 0 到 9 的數字組成。本問題區分大
    小寫。當 N=0 時,表示輸入結束。
    輸出格式:對於每一組測試數據,輸出一個整數,是所要求的最小數。
輸入樣例
5
Ab3bd
0
輸出樣例
2 

原字符串與其翻轉後的串求最長公共子序列,用字符串的長度減去最長公共子序列的長度即爲答案。

#include<bits/stdc++.h>

using namespace std;
const int N = 5005;
int dp[N][N], n;
char a[N], b[N];

int main() {
    while (scanf("%d", &n), n) {
        scanf("%s", a + 1);
        memcpy(b, a, sizeof(a));
        reverse(b + 1, b + n + 1);
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++) {
                if (a[i] == b[j])dp[i][j] = dp[i - 1][j - 1] + 1;
                else dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
            }
        printf("%d\n", n - dp[n][n]);
    }
    return 0;
}

一個小技巧,利用滾動數組可以將二維的dpdp數組壓縮成一維,節省空間。

#include<bits/stdc++.h>

using namespace std;
const int N = 5005;
int dp[2][N], n;
char a[N], b[N];

int main() {
    while (scanf("%d", &n), n) {
        scanf("%s", a + 1);
        memcpy(b, a, sizeof(a));
        reverse(b + 1, b + n + 1);
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++) {
                if (a[i] == b[j])dp[i & 1][j] = dp[i - 1 & 1][j - 1] + 1;
                else dp[i & 1][j] = max(dp[i - 1 & 1][j], dp[i & 1][j - 1]);
            }
        printf("%d\n", n - dp[n & 1][n]);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章