AtCoder Regular Contest 177 A - C

link

赛时: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 即得到最小花销。

image

一开始,我还很死板地闷想这双向边怎么快速地建,

其实在矩阵里完全不必用链式前向星还真去建个边出来,直接在 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;
}
posted @   Zhang_Wenjie  阅读(48)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示