AtCoder Regular Contest 177 A - C
赛时:300 + 400, rank 2001 吊车尾
A - Exchange
简单模拟,没有多想什么,直接贪心,总是先保证用较大的数去覆盖花销,应该是一种有解且较快的方法,同时显然的,我对花销从大到小进行排序,一遍过。
#include <bits/stdc++.h> #define re register int using namespace std; const int N = 20; struct number { int w, v; }num[N]; int n, shop[N], tot, need; bool cmp(int i, int j) { return i > j; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); num[1].w = 1, num[2].w = 5, num[3].w = 10, num[4].w = 50, num[5].w = 100, num[6].w = 500; for (re i = 1; i <= 6; i ++) { cin >> num[i].v; tot += num[i].v * num[i].w; } cin >> n; for (re i = 1; i <= n; i ++) { cin >> shop[i]; need += shop[i]; } if (tot < need) { cout << "No\n"; return 0; } sort(shop + 1, shop + n + 1, cmp); for (re i = 1; i <= n; i ++) for (re j = 6; j >= 1; j --) { if (!shop[i]) break; while (num[j].v > 0 && shop[i] - num[j].w >= 0) { shop[i] -= num[j].w; // cout << i << ' ' << j << ' ' << shop[i] << '\n'; num[j].v --; } } /* for (re i = 1; i <= n; i ++) cout << shop[i] << ' '; */ bool flag = false; for (re i = 1; i <= n; i ++) if (shop[i]) { flag = true; break; } if (flag) cout << "No\n"; else cout << "Yes\n"; return 0; }
B - Puzzle of Lamps
找规律的题目,一排灯有状态 0(OFF) 或 1(ON),有开(A:0->1)关(B:1->0),规定从左至右操作依次开灯或关灯,初始全部关闭,给出末状态,反推开关方案。
最重要的性质是,开关是规定从左至右依次控制灯,
意思就是,若 单独 讨论 i 位置上的灯为状态 1,它必然需要进行 i 次操作 A 得到。
显然,在 n 位置的灯满足这个讨论,
而在之前的灯的状态可能收到后边的灯的状态的影响,分类讨论即可,设当前 i 位置状态为 p,先前灯的状态为 q
- 若 p = 0,
- 若 q = 0,直接继承,无需操作;
- 若 q = 1,需要进行 i 次操作 B 使 i 灯泡由 1 -> 0;
- 若 p = 1,
- 若 q = 1, 直接继承,无需操作;
- 若 q = 0,需要进行 i 次操作 A 使 i 灯泡由 0 -> 1;
#include <bits/stdc++.h> #define re register int using namespace std; const int N = 50, M = 1e6 + 10; int n, cnt; string s; char ans[M]; int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> n; cin >> s; int last = -1; for (re i = n - 1; i >= 0; i --) { if (i == n - 1) { if (s[i] == '0') last = 0; if (s[i] == '1') { last = 1; for (re k = 1; k <= n; k ++) ans[++ cnt] = 'A'; } } else { if (s[i] == '0') { if (last == 0) continue; else { last = 0; for (re k = 1; k <= i + 1; k ++) ans[++ cnt] = 'B'; } } else { if (last == 1) continue; else { last = 1; for (re k = 1; k <= i + 1; k ++) ans[++ cnt] = 'A'; } } } } cout << cnt << '\n'; for (re i = 1; i <= cnt; i ++) cout << ans[i]; cout << '\n'; return 0; }
C - Routing
这题我一开始想用 dfs 做的,求四个点分别所在的连通快,再求 (1, 1) 与 (n, n) 所在连通块的最短距离,(n, 1) 和 (1, n) 同理,同时我也在想这两种路径会不会互相影响,
后边发现求最短距离不好做,会不会影响,能不能单独求解也没想明白,花好多时间结果打了个屎山代码。。。
首先要想明白 红线 和 蓝线 的路径求解会不会相互影响?
认为红色路径经过蓝色点变成的紫色点为需要 1 的花销,发现,红色路径走红点不产生花销,走蓝点产生 1 的花销,而再对于去求蓝色路径,并不关心蓝点是否变为紫点,关心的是会产生花销为 1 的红点,因为求红色路径并不改变图中的红点,所以 红色路径和蓝色路径的花销是相互独立的。
所以,这题就可以简化为求两点间的最小花销,
可以用 最短路 求解,对相邻点建双向边,同色点边权为 0,异色点边权为 1,跑一遍 dijkstra 即得到最小花销。
一开始,我还很死板地闷想这双向边怎么快速地建,
其实在矩阵里完全不必用链式前向星还真去建个边出来,直接在 bfs 里走图就是了,这是我思维不足的地方。
注意:使用 tuple 时,把要比较的值放在第一维。
#include <bits/stdc++.h> #define re register int using namespace std; typedef tuple<int, int, int> tp; const int N = 510, inf = 0x3f3f3f3f; const int dx[4] = {-1, 0, 1, 0}; const int dy[4] = {0, 1, 0, -1}; char g[N][N]; int n, res1, res2, dist[N][N]; bool vis[N][N]; priority_queue< tp, vector<tp>, greater<tp> > q; inline int work(int sx, int sy, int ex, int ey, char c) { memset(vis, false, sizeof(vis)); for (re i = 1; i <= n; i ++) for (re j = 1; j <= n; j ++) dist[i][j] = inf; dist[sx][sy] = 0; q.push(make_tuple(0, sx, sy)); while (!q.empty()) { int x = get<1>(q.top()), y = get<2>(q.top()); q.pop(); if (vis[x][y]) continue; vis[x][y] = true; for (re i = 0; i < 4; i ++) { int tx = x + dx[i], ty = y + dy[i]; if (tx < 1 || tx > n || ty < 1 || ty > n) continue; int w = (g[tx][ty] == c ? 0 : 1); if (dist[x][y] + w < dist[tx][ty]) { dist[tx][ty] = dist[x][y] + w; q.push(make_tuple(dist[tx][ty], tx, ty)); } } } /* for (re i = 1; i <= n; i ++) { for (re j = 1; j <= n; j ++) cout << dist[i][j] << ' '; cout << '\n'; } */ return dist[ex][ey]; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> n; for (re i = 1; i <= n; i ++) for (re j = 1; j <= n; j ++) cin >> g[i][j]; res1 = work(1, 1, n, n, 'R'); res2 = work(1, n, n, 1, 'B'); cout << res1 + res2 << '\n'; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具