最近网课也开始了,牛客上一堆比赛题目也没补,所以就D题后面的也懒得补了
A.Three String
水题
#include <cstdio> #include <cstring> using namespace std; char a[100010], b[100010], c[100010]; int main() { int t; scanf("%d", &t); while (t--) { memset(a, 0, sizeof(a)); memset(b, 0, sizeof(b)); memset(c, 0, sizeof(c)); scanf("%s%s%s", a, b, c); int len = strlen(a), ans = 0; for (int i = 0; i < len; i++) { if (c[i] == a[i] || c[i] == b[i]) continue; ans = -1; break; } if (ans == -1) puts("NO"); else puts("YES"); } return 0; }
B.Motarack's Birthday
其实也挺水的...但是我场上脑子有点问题,第一反应是三分(?)因为它应该是只有一个极值的函数,可以用三分来做
这是我的代码,写的很复杂而且很奇怪
#include <cstdio> #include <cmath> #include <algorithm> using namespace std; const int N = 1e5 + 10; int a[N], n; inline int val(int b) { int maxn = 0; for (int i = 2; i <= n; i++) { if (a[i - 1] == -1 && a[i] == -1) continue; if (a[i - 1] == -1) maxn = max(maxn, (int)abs(b - a[i])); else if (a[i] == -1) maxn = max(maxn, (int)abs(b - a[i - 1])); else maxn = max(maxn, (int)abs(a[i] - a[i - 1])); } return maxn; } int main() { int t; scanf("%d", &t); while (t--) { scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); int l = 0, r = 1e9; while (r - l >= 3) { int l1 = l + (r - l) / 3; int r1 = r - (r - l) / 3; int a = val(l1), b = val(r1); if (a <= b) r = r1; else l = l1; } int a, b = 1e9 + 7; if (l != r) { for (int i = l; i <= r; i++) { int z = val(i); if (z < b) b = z, a = i; } } else a = l, b = val(l); printf("%d %d\n", b, a); } return 0; }
然后题解肯定不是这样的啦,最后答案的范围肯定在和-1相邻的数字之间,若这些数字中最大的是maxn, 最小的是minn,则差的最大就是max(abs(maxn - val), abs(minn - val)),所以val等于(maxn + minn)/2就行了,代码很简单,我也懒得写了。
C.Ayoub's function
场上想了很久(还是太菜了),后来突然灵机一动,想到可以用总数减去只有0的个数,然后就可以发现000...000的序列越短越好,然后就可以直接O(1)出来了。
#include <cstdio> using namespace std; int main() { int t; scanf("%d", &t); while (t--) { long long n, m; scanf("%lld %lld", &n, &m); long long ans = 1ll * n * (1 + n) / 2; if ((n - m) % (m + 1) == 0) { long long b = (n - m) / (m + 1); ans -= 1ll * (m + 1) * b * (b + 1) / 2; } else { long long b = (n - m) / (m + 1); long long c = (n - m) % (m + 1); ans -= (m + 1 - c) * b * (b + 1) / 2; ans -= c * (b + 1) * (b + 2) / 2; } printf("%lld\n", ans); } return 0; }
D.Time to Run
很容易发现它是欧拉通路,因为它没有奇度顶点,然后想一个构造的方法就行了,然后我就随便想了一个,结果有一堆细节上的问题QAQ
#include <cstdio> #include <algorithm> using namespace std; int main() { int n, m, k; scanf("%d %d %d", &n, &m, &k); int r = 4 * m * n - 2 * n - 2 * m; if (k > r) { puts("NO"); return 0; } puts("YES"); n--; m--; //RDU if (k == 0) return 0; if (n == 0) { //这种情况要特殊考虑 if (k <= m) { puts("1"); printf("%d R\n", k); } else { puts("2"); printf("%d R\n%d L", m, k - m); } return 0; } if (m == 0) { //同上 if (k <= n) printf("1\n%d D\n", k); else printf("2\n%d D\n%d U\n", n, k - n); return 0; } int kk = k; int t = 1, cnt = 0; while (k > 0) { //第一遍先找要多少次操作 if (t == (n + 1)) { if (k <= m) { cnt++; break; } else { cnt++; k -= m; } if (k <= m) { cnt++; break; } else { cnt++; k -= m; } if (k <= n) { cnt++; break; } else { cnt++; k -= m; } break; } if (k <= m * 3) { if (k / 3 > 0) cnt++; int y = k % 3; if (y == 1) cnt++; else if (y == 2) cnt++; break; } else { cnt++; k -= m * 3; } if (k <= m) { cnt++; break; } else { cnt++; k -= m; } cnt++; k--; t++; } t = 1; k = kk; printf("%d\n", cnt); while (k > 0) { if (t == (n + 1)) { //这个要注意,最后一行就要往回走 if (k <= m) { printf("%d R\n", k); break; } else { printf("%d R\n", m); k -= m; } if (k <= m) { printf("%d L\n", k); break; } else { printf("%d L\n", m); k -= m; } if (k <= n) { printf("%d U\n", k); break; } else { printf("%d U\n", m); k -= m; } break; } if (k <= m * 3) { if (k / 3 > 0) printf("%d RDU\n", k / 3); int y = k % 3; if (y == 1) puts("1 R"); else if (y == 2) puts("1 RD"); break; } else { printf("%d RDU\n", m); k -= m * 3; } if (k <= m) { printf("%d L\n", k); break; } else { printf("%d L\n", m); k -= m; } printf("1 D\n"); k--; t++; } return 0; }