A
只要遍历字符串,判断是先遇到钥匙还是先遇到门就行。
AC代码:
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
| #include <iostream> #include <algorithm> #include <cstdio> #include<cstring> using namespace std; bool f[3]; string key = "rgb", door = "RGB"; int main() { int n; cin >> n; while(n--) { string s; cin >> s; bool flag = true; memset(f, false, sizeof f); for (int i = 0; i < s.length();i++) { for (int j = 0; j < 3;j++) { if(s[i]==key[j]) { f[j] = true; break; } } for (int j = 0; j < 3;j++) { if(s[i]==door[j]&&!f[j]) { flag = false; break; } } if(!flag) break; } if(flag) cout << "YES" << endl; else cout << "NO" << endl; } return 0; }
|
B
仔细观察发现1,2,3…n中只有1+2=3,所以只要破坏1,2,3这种顺序即可。可以把1放到最后,然后2-(n-1)轮换输出,这样有n-1种结果。最后一种可以输出1,n,2,3…
AC 代码:
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
| #include <iostream> #include <algorithm> #include <cstdio> #include <cstring> using namespace std; int main() { int T; cin >> T; while (T--) { int n; cin >> n; for (int i = 0; i < n-1; i++) { for (int j = 2 + i; j <= n; j++)
cout << j << ' ';
for (int j = 1 + i; j >= 1; j--) cout << j << ' '; puts(""); }
cout << 1 << ' ' << n<<' '; for (int i = 2; i < n;i++) cout << i << ' '; puts(""); } return 0; }
|
C
这题和最大子区间和差不多,不同点是f(k)可以在所以数中挑选k个加上x。可以先计算出长度为i的最大子区间的和,长度为i的最大子区间的和加上i个x后仍最大,最后遍历不同长度的最大子区间和输出最大值即可。
AC代码:
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
| #include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N = 5005;
int a[N], pdp[N], dp[N], sum[N]; int main() { int T, n, x; cin >> T; while (T--) { cin >> n >> x; for (int i = 1; i <= n; i++) { cin >> a[i]; sum[i] = sum[i - 1] + a[i]; pdp[i] = -1e9; } for (int i = 1; i <= n; i++) { for (int j = 1; j + i - 1 <= n; j++) { int l = j, r = i + j - 1; pdp[i] = max(pdp[i], sum[r] - sum[l - 1]); } } for (int k = 0; k <= n; k++) { for (int i = 1; i <= n; i++) { dp[i] = pdp[i] + min(k, i) * x; } int ma = 0; for (int i = 1; i <= n; i++) ma = max(ma, dp[i]); cout << ma << ' '; } puts(""); } return 0; }
|
D
后面的涂色会覆盖前面的,所以只有后面的涂色有效。一开始想到的是模拟,不过数据范围2e5开不了二维数组。只要倒序遍历涂色,记录最终局面有几次有x次效涂色,答案就是看k^x。数据大要开long long
AC代码:
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
| #include <iostream> #include <cstring> #include <algorithm> #include <map> using namespace std; const int N = 2e5 + 3,mod = 998244353 ; typedef long long ll; int x[N], y[N]; int main() { int T; scanf("%d", &T); while (T--) { int n, m, k, q; scanf("%d%d%d%d", &n, &m, &k, &q); for (int i = 0; i < q; i++) scanf("%d%d", x + i, y + i); map<ll, ll> xx, yy; ll ans = 1; int cntx = 0, cnty = 0; for (int i = q - 1; i >= 0; i--) { if(cntx==n||cnty==m) break; bool f = false; if(!xx[x[i]]) { xx[x[i]] = 1; cntx++; f = true; } if(!yy[y[i]]) { yy[y[i]] = 1; cnty++; f = true; } if(f) ans = ((ans % mod) * (k % mod)) % mod; } printf("%lld\n", ans); } return 0; }
|