牛客周赛 Round 80
A. 棋盖放子
点击查看代码
void solve() {
int x, y;
std::cin >> x >> y;
if (y > x) {
std::cout << "quit the competition!\n";
} else {
std::cout << x - y << "\n";
}
}
B. 训练参赛
题意:
可以看作一维上有
点击查看代码
void solve() {
int n;
std::cin >> n;
std::vector<int> a(2 * n);
for (int i = 0; i < 2 * n; ++ i) {
std::cin >> a[i];
}
std::sort(a.begin(), a.end());
int ans = 0;
for (int i = 1; i < 2 * n; i += 2) {
ans += a[i] - a[i - 1];
}
std::cout << ans << "\n";
}
C. 举手赢棋easy
题意:一个人01串,你可以改变一个位置的值,满足任何一个前缀的1都比0多。求有多少方案。
从前到后模拟一些,出现的第一个位置0比1多,那就必须要把前面的0变成1,然后更新下前缀,如果后面还有0比1多的情况,就无解了。
如果没有0比1多的情况,那么随便放。
D. 举手赢棋hard
题意:和
也是模拟一下,记录每个0比1多的位置到上一次0比1多的位置的0的个数,可以看作以这样的位置分段。然后记录有几个这样的位置。如果大于两个,则答案为0。如果有两个,则可以在第一段的0里选一个和第二段的0里选一个,也可以在第一段的0里选两个。如果有一个,则可以在第一段0里选一个和在其他位置选任意一个,或者在第一段里选两个。如果没有这样的位置,答案是
点击查看代码
void solve() {
i64 n;
std::cin >> n;
std::string s;
std::cin >> s;
i64 sum = 0, cnt = 0, cnt1[2]{}, flag = 0;
for (int i = 0; i < n; ++ i) {
sum += s[i] == '1' ? 1 : -1;
cnt += s[i] == '0';
if (sum < 0) {
if (flag < 2) {
cnt1[flag] = cnt;
}
++ flag;
cnt = 0;
sum += 2;
}
}
if (flag > 2) {
std::cout << 0 << "\n";
} else if (flag == 2) {
std::cout << cnt1[0] * (cnt1[0] - 1) / 2 + cnt1[0] * cnt1[1] << "\n";
} else if (flag == 1) {
std::cout << cnt1[0] * (n - cnt1[0]) + cnt1[0] * (cnt1[0] - 1) / 2 << "\n";
} else if (flag == 0) {
std::cout << n * (n - 1) / 2 << "\n";
}
}
E. 公平对局
题意:给你一个围棋局面,求放一个黑棋最多可以吃多少白棋。
遍历每个白棋的联通块,如果这个联通块只有一口气,那么唯一和它连接的空格可以吃掉这个联通块,把贡献加到这个空格上去。最后取每个空格可以吃掉白棋的最大值就行。
点击查看代码
void solve() {
int n;
std::cin >> n;
std::vector<std::string> s(n);
for (int i = 0; i < n; ++ i) {
std::cin >> s[i];
}
const int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
int size;
std::set<std::pair<int, int>> set;
std::vector st(n, std::vector<int>(n));
auto dfs = [&](auto self, int x, int y) -> void {
++ size;
st[x][y] = 1;
for (int i = 0; i < 4; ++ i) {
int nx = x + dx[i], ny = y + dy[i];
if (nx < 0 || nx >= n || ny < 0 || ny >= n) {
continue;
}
if (s[nx][ny] == '.') {
set.insert({nx, ny});
continue;
}
if (st[nx][ny] || s[nx][ny] == '#') {
continue;
}
self(self, nx, ny);
}
};
std::vector sum(n, std::vector<int>(n));
for (int i = 0; i < n; ++ i) {
for (int j = 0; j < n; ++ j) {
if (!st[i][j] && s[i][j] == '*') {
size = 0;
set.clear();
dfs(dfs, i, j);
if (set.size() == 1) {
auto [x, y] = *set.begin();
sum[x][y] += size;
}
}
}
}
int ans = 0;
for (int i = 0; i < n; ++ i) {
for (int j = 0; j < n; ++ j) {
ans = std::max(ans, sum[i][j]);
}
}
std::cout << ans << "\n";
}
F. 训练参赛(二)
神秘构造,看
待补。
G. 不公平对局
题意:两个人每回合有概率吃掉对方一个棋子,最先吃到
转移方程为
发现右边也有
就是考虑每种情况就行了,还是很简单的。不过当
点击查看代码
void solve() {
int n, a1, b1, a2, b2;
std::cin >> n >> a1 >> b1 >> a2 >> b2;
Z p1 = (Z)a1 / b1, p2 = (Z)a2 / b2;
Z p3 = 1 / (1 - (1 - p1) * (1 - p2));
if (a1 == b1 && a2 == b2) {
std::cout << 0 << "\n";
return;
}
std::vector f(n + 1, std::vector<Z>(n + 1));
for (int i = 0; i <= n; ++ i) {
for (int j = 0; j <= n; ++ j) {
if (i == 0 && j == 0) {
f[i][j] = 1;
} else {
if (j != n && i && p2 != 1) {
f[i][j] += f[i - 1][j] * p1 * (1 - p2);
}
if (i != n && j && p1 != 1) {
f[i][j] += f[i][j - 1] * (1 - p1) * p2;
}
if (i && j) {
f[i][j] += f[i - 1][j - 1] * p1 * p2;
}
f[i][j] = f[i][j] * p3;
}
}
}
Z ans = 0;
for (int i = 0; i < n; ++ i) {
ans += f[i][n];
}
std::cout << ans << "\n";
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具