CCZU ACM 算法设计课 期末考试 1 参考答案
1卷
出题人觉得用python可以更优雅地表现算法
A
1 2 3 4 5 6 7 8 9
| n, m = map(int, input().split())
ans = list(map(int, input().split()))
st = set(map(int, input().split()))
for i in ans: if i in st: print(i, end=' ')
|
B
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| from collections import defaultdict import heapq
def find(x): return x[0]
n, m = map(int, input().split()) ans = defaultdict(int) heap = []
power = list(map(int, input().split())) coins = list(map(int, input().split())) num = list(i for i in range(n+1))
knt = list(zip(power, coins, num))
knt.sort(key=find)
Sum = 0
for i in knt: ans[i[2]] = i[1] + Sum heapq.heappush(heap, i[1]) Sum += i[1] if len(heap) > m: Sum -= heapq.heappop(heap)
for i in range(n): print(ans[i], end=' ')
|
C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| #include <bits/stdc++.h> using namespace std;
set<string> s;
int main() { ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int n; string a;
cin >> n; int book[26] = {}; while(n --) { string tmp = ""; memset(book, 0, sizeof(book));
cin >> a; for(auto& i: a) book[i-'a'] = 1; for(int i = 0; i < 26; i++) tmp += to_string(book[i]); s.insert(tmp); }
cout << s.size() << endl; return 0; }
|
D
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| #include <bits/stdc++.h> using namespace std;
int main() { int n, w; ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
cin >> n >> w; vector<int> v; v.resize(n);
for(int i = 0; i < n; i++) cin >> v[i];
int cnt = 0; int Max = -w-1; int Min = w+1; for(auto& i: v) { cnt += i; if(cnt < -w or cnt > w) { cout << 0 << endl; return 0; }
Max = max(Max, cnt); Min = min(Min, cnt); }
int r = (Max) > 0 ? (w - Max) : w; int l = (Min) < 0 ? abs(Min) : 0;
if(l > r) cout << 0 << endl; else cout << r - l + 1 << endl;
return 0; }
|
2卷
A
1 2 3 4 5 6 7 8 9 10 11
| #include <bits/stdc++.h> using namespace std;
int main() { int n; cin >> n; int s = n % 60; int m = (n / 60) % 60; int h = n / 3600; printf("%d:%d:%d\n", h, m, s); }
|
B
原样输出,不要被浮点数迷惑了
1 2 3 4 5 6 7 8
| #include <bits/stdc++.h> using namespace std;
int main() { string s; cin >> s; cout << s; }
|
C
先找到较小的那个质数因子,然后就能直接求出较大的那个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #include <bits/stdc++.h> using namespace std;
inline bool isprime(int n) { int sq = sqrt(n); for (int i = 2; i <= sq; i++) if (n % i == 0) return false; return true; }
int main() { int n; cin >> n; for (int i = 2; i < n; i++) if (n % i == 0 && isprime(i)) { cout << n / i << endl; return 0; } }
|
D
对于每一个重复的数字,用它和序列中的最大值求和,保留新求出的和,删掉那个重复数字。因为是和最大值求和,一定不会于序列中已有的元素重复,并且这个新求出来的和将成为下次操作用到的最大值。因此每个重复的数字都能用一次操作去掉,还不会产生副作用,题目就是求有多少重复数字。
1 2 3 4 5 6 7 8 9 10 11 12
| #include <bits/stdc++.h> using namespace std;
int main() { int n; cin >> n; vector<int> a(n); for (int i = 0; i < n; i++) cin >> a[i]; sort(a.begin(), a.end()); cout << a.end() - unique(a.begin(), a.end()) << endl; }
|
3卷
A
数据范围只有无符号64位整数才能放下
1 2 3 4 5 6 7 8 9
| #include <bits/stdc++.h> using namespace std;
int main() { unsigned long long t,maxn=0; while (cin >> t) maxn=max(maxn,t); cout << maxn << endl; }
|
B
两数之积除以最大公约数即可 最大公约数用辗转相除法或者调用内置函数求解
1 2 3 4 5 6 7 8
| #include <bits/stdc++.h> using namespace std;
int main() { int a, b; cin >> a >> b; cout << a / __gcd(a, b) * b << endl; }
|
C
手动逐个字符检查计数也可以,没什么技术含量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| #include <bits/stdc++.h> using namespace std;
const char delim[] = " ~!@#$%^&*()_+`-=[]\\{}';':\",./<>?\n";
int main() { char s[100]; fgets(s, sizeof(s), stdin); char *p = strtok(s, delim); int cnt = 0; while (p) { cnt++; cout << p << endl; p = strtok(0, delim); } cout << cnt << endl; }
|
D
化简成ax=b的形式 遇到非数字就提交刚才的数字到a或者b上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| #include <bits/stdc++.h> using namespace std;
int main() { string eq; getline(cin, eq); double a = 0, b = 0; int sign = 1, sign2 = 1; string buf; char unknown; for (auto p = eq.begin(); p <= eq.end(); ++p) { if (!isdigit(*p)) { int cmt = atoi(buf.c_str()); if (buf.size() == 0 && isalpha(*p)) cmt = 1; cmt *= sign * sign2; buf.clear();
if (isalpha(*p)) { unknown = *p; a += cmt; } else { b -= cmt; if (*p == '+') sign = 1; else if (*p == '-') sign = -1; else if (*p == '=') sign = 1, sign2 = -1; } } else { buf.push_back(*p); } } double res = b / a; if (res == 0) res = 0; printf("%c=%.3f\n", unknown, res); }
|