2024年6月CSP,回顾+题解。
等题目出来后补充题解。
回顾
整体相较上次有进步,题目变难了一点点,得分360/500
。
第一、二题比较容易,花了20分钟过掉了。
第三题大模拟花了两个多小时,只拿了40
分,剩下的点全部MLE了,考场上以为是自己的问题,回来看榜发现全国只有6个人过掉了大模拟QuQ,谁家正经考试把压轴放正中间啊QuQ。
然后看完了四五题题目,发现第五题考察的似乎是一个二维的区间最值问题,感觉过不掉,遂打了一个暴力,拿20分。(感觉再做做优化一下也可以多拿点)
第四题动态规划,分组背包,抢着在最后40分钟过掉了,保住了300分。
Conclusion:第三题太抽象。
题解
A. 矩阵重塑(其一)
题意:给一个 n * m 大小矩阵,用 p * q 的大小重新排布矩阵。
分析:用一维数组接收,改变输出格式即可。
完整代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #include<bits/stdc++.h> #define int long long using namespace std;
inline int read(){ int x = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { x = x * 10 + ch - 48; ch = getchar(); } return x * f; }
signed main(){ int n = read(), m = read(), p = read(), q = read(); vector<int>v(n * m); for(auto &i : v) i = read(); for(int i = 0; i < p; i ++){ for(int j = 0; j < q; j++){ cout << v[i * q + j] << ' '; } puts(""); } return 0; }
|
B. 矩阵重塑(其二)
题意:实现 查询、重塑、转置 三个操作。(转置操作不超过100次)
分析:依然使用一维数组接收,查询操作O(1)
,重塑操作只要改变记录的行列数即可,O(1)
,题目告诉我们转置操作次数很少,直接暴力给数组重新按转置的方式赋值即可,O(mn)
。
完整代码:
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 37
| #include<bits/stdc++.h> #define int long long using namespace std;
inline int read(){ int x = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { x = x * 10 + ch - 48; ch = getchar(); } return x * f; }
signed main(){ int n = read(), m = read(), t = read(); vector<int>v(n * m); for(auto &i : v) i = read(); while(t--){ int op = read(), a = read(), b = read(); if(op == 1){ n = a, m = b; } else if(op == 2){ vector<int>tmp(n * m); for(int i = 0; i < n; i++) { for(int j = 0; j < m; j++){ tmp[j * n + i] = v[i * m + j]; } } v = tmp; swap(n, m); } else{ cout << v[a * m + b] << '\n'; } }
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 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| #include<bits/stdc++.h> #define int long long using namespace std;
inline int read(){ int x = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { x = x * 10 + ch - 48; ch = getchar(); } return x * f; }
const int N = 1005, M = 1e4; int b[N], c[N]; int a[N][N], sz[N], d[N][N], dp[M];
bool cmp(int x, int y){ return x > y; }
signed main(){ int n = read(), m = read(), v = read(); for(int i = 0; i < n; i++){ b[i] = read(), c[i] = read(); } for(int i = 0; i < m; i++){ int w = read(), t = read(); a[t][sz[t]++] = w; } for(int i = 0; i < n; i++) sort(a[i], a[i] + sz[i], cmp); for(int i = 0; i < n; i++){ for(int j = 1; j < sz[i]; j++){ a[i][j] += a[i][j - 1]; } } for(int i = 0; i < n; i++){ for(int j = 0; j < sz[i]; j++){ d[i][j] = (j + 1) * c[i] + b[i]; a[i][j] -= d[i][j]; } }
for(int i = 0; i < n; i++){ for(int j = M - 1; j >= 0; j--){ for(int k = 0; k < sz[i]; k++){ if(d[i][k] <= j) dp[j] = max(dp[j], dp[j - d[i][k]] + a[i][k]); } } } int mn = 0; for(int i = 0; i < M; i++){ if(dp[i] >= v){ mn = i; break; } } cout << mn; return 0; }
|
成绩