Codeforces Round #760 (Div. 3)
Codeforces Round #760 (Div. 3)
比赛的时候做了 .
A. Polycarp and Sums of Subsequences
标签:模拟
仔细观察发现 恰好对应 , 然后 就是第 3 项或第 4 项.
由于问题保证有解,所以只需判断一下是否是第三项即可.
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 | #include <bits/stdc++.h> #define ll long long #define pb push_back #define setIO(s) freopen(s".in","r",stdin) using namespace std; int a[10], b[10]; vector< int >g; int check( int x, int y, int z) { g.clear(); g.pb(x); g.pb(y); g.pb(z); g.pb(x + y); g.pb(x + z); g.pb(y + z); g.pb(x + y + z); sort(g.begin(), g.end()); for ( int i = 1; i <= 7; ++ i) { if (a[i] != g[i - 1]) return 0; } return 1; } void solve() { int n = 7; for ( int i = 1; i <= n ; ++ i) { scanf ( "%d" , &a[i]); } //b[1] = a[1], b[2] = a[2]; if (check(a[1], a[2], a[3])) { printf ( "%d %d %d\n" , a[1], a[2], a[3]); } else { printf ( "%d %d %d\n" , a[1], a[2], a[4]); } } int main() { // setIO("input"); int T; scanf ( "%d" , &T); while (T-- ) solve(); return 0; } |
B. Missing Bigram
标签:模拟
如果可以直接输出的话就在末尾随便加一个字符.
否则可以在不合法的位置选择输出两个字符,其余位置输出一个即可.
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 | #include <bits/stdc++.h> #define ll long long #define N 2009 #define setIO(s) freopen(s".in","r",stdin) using namespace std; char str[N][2]; void solve() { int n ; scanf ( "%d" , &n); for ( int i = 1; i <= n - 2; ++ i) { scanf ( "%s" , str[i]); } printf ( "%c%c" , str[1][0], str[1][1]); int flag = 0; for ( int i = 2; i <= n - 2; ++ i) { if (str[i - 1][1] != str[i][0]) { flag = 1; printf ( "%c%c" , str[i][0], str[i][1]); } else { printf ( "%c" , str[i][1]); } } if (!flag) printf ( "%c" , 'a' ); printf ( "\n" ); } int main() { // setIO("input"); int T; scanf ( "%d" , &T); while (T -- ) solve(); return 0; } |
C. Paint the Array
标签: 相关.
可以枚举是奇数下标还是偶数下标可以被钦定的 整除.
那么显然这个 必须是所有数字的 .
然后显然对于不能被 整除的位置条件应该苛刻,所以直接取 作为答案即可.
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 <bits/stdc++.h> #define N 104 #define ll long long #define pb push_back #define setIO(s) freopen(s".in","r",stdin) using namespace std; ll a[N]; int n ; vector<ll>g[2]; ll gcd(ll x, ll y) { return y ? gcd(y, x % y ) : x; } ll lcm(ll x, ll y) { return x / gcd(x, y) * y; } ll sol( int o) { if (!g[o].size()) return 0; ll gc = g[o][0]; for ( int i = 0 ; i < g[o].size() ; ++ i) { gc = gcd(gc, g[o][i]); } for ( int i = 0; i < g[o ^ 1].size() ; ++ i) { if (g[o ^ 1][i] % gc == 0) return 0; } return gc; } void solve() { scanf ( "%d" , &n); g[0].clear(); g[1].clear(); for ( int i = 1; i <= n ; ++ i) { scanf ( "%lld" , &a[i]); g[i % 2].pb(a[i]); } // d comes from g[0] ll p = max(sol(0), sol(1)); printf ( "%lld\n" , p); } int main() { //setIO("input"); int T; scanf ( "%d" , &T); while (T -- ) solve(); return 0; } |
D. Array and Operations
标签:贪心,众数
贪心选择将最大的 个数字操作掉.
那么操作这些数字的时候贡献要么是 要么是 .
只需把众数的个数拿出来,然后讨论一下是否会出现 的情况即可.
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 | #include <bits/stdc++.h> #define N 1004 #define setIO(s) freopen(s".in","r",stdin) using namespace std; int n , a[N], bu[200009], K; bool cmp( int i, int j) { return i > j; } void solve() { scanf ( "%d%d" , &n, &K); for ( int i = 1; i <= n ;++ i) { scanf ( "%d" , &a[i]); //bu[a[i]] ++ ; } sort(a + 1, a + 1 + n, cmp); for ( int i = 1; i <= 2 * K ; ++ i) { bu[a[i]] ++ ; } int sum = 0; for ( int i = 2 * K + 1; i <= n ; ++ i) sum += a[i]; int mx = 0; for ( int i = 1; i <= 2 * K ; ++ i) mx = max(mx, bu[a[i]]); if (mx > K) { int c1 = mx, c2 = 2 * K - mx; sum += (c1 - c2) / 2; } for ( int i = 1; i <= n ; ++ i) bu[a[i]] = 0; printf ( "%d\n" , sum); } int main() { // setIO("input"); int T; scanf ( "%d" , &T); while (T--) solve(); return 0; } |
E. Singers' Tour
标签:模拟,性质分析
显然可以直接确定 之和.
然后可以考虑相邻的 之间的不同,发现这个不同是 .
然后就能将 解出来了,答案其实是唯一的.
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 | #include <bits/stdc++.h> #define N 100009 #define ll long long #define setIO(s) freopen(s".in","r",stdin) using namespace std; int n; ll b[N], a[N]; void solve() { scanf ( "%d" , &n); ll sum = 0; for ( int i = 1; i <= n ; ++ i) { scanf ( "%lld" , &b[i]); sum += b[i]; } ll tot = 1ll * (n + 1) * n / 2; if (sum % tot) { printf ( "NO\n" ); return ; } // // b[i] = b[i - 1] + sum(a[i]) - (n - 1) * a[i]; ll pa = sum / tot; // printf("%lld\n", pa); for ( int i = 1; i <= n ; ++ i) { int prev = (i - 2 + n) % n + 1; ll det = (b[prev] - b[i] + pa); // printf("%lld %lld %lld %lld\n",b[prev], b[i], det, pa); if (det <= 0) { printf ( "NO\n" ); return ; } if (det % n) { printf ( "NO\n" ); return ; } a[i] = det / n; } printf ( "YES\n" ); for ( int i = 1; i <= n; ++ i) { printf ( "%lld " , a[i]); } printf ( "\n" ); // exit(0); } int main() { // setIO("input"); int T; scanf ( "%d" , &T); while (T -- ) solve(); return 0; } |
F. Reverse
标签:二进制,模拟
不难发现加 0 的操作就是将二进制序列翻转,然后 + 1 的操作是 + 1 后翻转.
由于每个数字最多会有 2 个分叉,所以直接暴力搜索用 记录一下即可.
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 | #include <bits/stdc++.h> #define ll long long #define pb push_back #define setIO(s) freopen(s".in","r",stdin) using namespace std; int bu[103]; map<ll, int >vs; ll bin[103], X, Y; void init() { for ( int i = 0; i < 64 ; ++ i) bin[i] = 1ll << i; } ll rev(ll x) { int le = 0; while (x) { bu[++ le] = x & 1; x >>= 1; } ll tp = 0; for ( int i = 1; i <= le; ++ i) { tp += 1ll * bu[i] * bin[le - i]; } // printf("%lld qaq\n", tp); // exit(0); return tp; } int get_len(ll x) { int le = 0; while (x) { ++ le; x >>= 1; } return le; } void dfs(ll x) { // printf("%lld\n", x); vs[x] = 1; if (x == Y) { printf ( "YES\n" ); exit (0); } ll tmp = rev(x); ll t1 = rev(x * 2 + 1); // printf("%lld %lld\n", tmp, t1); // printf("%d %d\n", get_len(t1), get_len(tmp)); if (!vs[t1] && get_len(t1) <= get_len(Y)) { dfs(t1); // +1 后翻转. } if (!vs[tmp] && get_len(tmp) <= get_len(Y)) { dfs(tmp); } } int main() { // setIO("input"); init(); scanf ( "%lld%lld" , &X, &Y); dfs(X); printf ( "NO\n" ); return 0; } |
G. Trader Problem
标签:并查集
可以把所有数字放到一起排序,那么如果一个数字可以达到第一个比他大的数字就连边.
然后数字序列就构成了若干个连通块,每一个连通块的贡献就是前 大的数字和.
这里 代表这个连通块中包含初始数字的个数.
这个模型可以将询问离线从小到大排序,然后挨个合并并查集即可.
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 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | #include <bits/stdc++.h> #define N 400009 #define ll long long #define pb push_back #define setIO(s) freopen(s".in","r",stdin) using namespace std; int n, m, Q; struct Query { int K, id; Query( int K = 0, int id = 0):K(K), id(id) {} }q[N]; bool cq(Query i, Query j) { return i.K < j.K; } int num[N]; ll ans[N], sum[N], fin[N]; struct Node { int x, id; Node( int x = 0, int id = 0):x(x),id(id){} }A[N]; bool cmp(Node i, Node j) { return i.x < j.x; } struct DET { int pos, det; DET( int pos = 0, int det = 0):pos(pos), det(det){} }arr[N]; int fa[N]; int find( int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); } bool DE(DET i, DET j) { return i.det < j.det; } ll ou[N]; int main() { // setIO("input"); scanf ( "%d%d%d" , &n, &m, &Q); for ( int i = 1; i <= n ; ++ i) { scanf ( "%d" , &A[i].x); A[i].id = 1; } for ( int i = 1; i <= m ; ++ i) { scanf ( "%d" , &A[i + n].x); A[i + n].id = 0; } int tot = n + m; ll ans = 0; sort(A + 1, A + 1 + tot, cmp); for ( int i = 1; i <= tot; ++ i) { sum[i] = sum[i - 1] + A[i].x; if (A[i].id) ans += A[i].x; } // printf("%lld\n", ans); for ( int i = 1; i <= tot; ++ i) { fa[i] = i; if (A[i].id == 1) num[i] = 1, fin[i] = A[i].x; } for ( int i = 1; i < tot; ++ i) { int de = A[i + 1].x - A[i].x; arr[i] = DET(i, de); } sort(arr + 1, arr + tot, DE); for ( int i = 1; i <= Q; ++ i) { int kth; scanf ( "%d" , &kth); q[i] = Query(kth, i); } sort(q + 1, q + 1 + Q, cq); for ( int i = 1, j = 1; i <= Q; ++ i) { for (; j <= (tot - 1) && arr[j].det <= q[i].K; ++ j) { int p = arr[j].pos; int ori = sum[p]; fa[p] = p + 1; int now = find(fa[p]); num[now] += num[p]; ans -= fin[p]; ans -= fin[now]; fin[now] = sum[now] - sum[now - num[now]]; ans += fin[now]; } ou[q[i].id] = ans; } for ( int i = 1; i <= Q; ++ i) { printf ( "%lld\n" , ou[i]); } return 0; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY