2025牛客寒假算法基础集训营5
A. 小L的三则运算
题意:给定结果和运算符,求一个合法的式子。
分情况讨论即可。
点击查看代码
void solve() {
i64 x;
char c;
std::cin >> x >> c;
if (c == '+') {
std::cout << 1 << " " << x - 1 << "\n";
} else if (c == '-') {
std::cout << x + 1 << " " << 1 << "\n";
} else if (c == '*') {
std::cout << 1 << " " << x << "\n";
}
}
B. 小L出师了
题意:在
显然我们应该每隔
点击查看代码
void solve() {
i64 n, t, k;
std::cin >> n >> t >> k;
std::cout << std::min((n - k) / t, k + 1) << "\n";
}
C. 小L的位运算
题意:给你三个二进制串
先把异或值不等于
点击查看代码
void solve() {
int n, x, y;
std::cin >> n >> x >> y;
std::string a, b, c;
std::cin >> a >> b >> c;
i64 ans = 0, cnt[2][2]{};
for (int i = 0; i < n; ++ i) {
if (((a[i] - '0') ^ (b[i] - '0')) != c[i] - '0') {
++ cnt[a[i] - '0'][b[i] - '0'];
}
}
if (x * 2 <= y) {
ans = (i64)x * (cnt[0][1] + cnt[1][0] + cnt[0][0] + cnt[1][1]);
} else {
std::vector<i64> a{cnt[0][0], cnt[0][1], cnt[1][0], cnt[1][1]};
std::sort(a.begin(), a.end());
if (a[3] >= a[0] + a[1] + a[2]) {
ans += (a[0] + a[1] + a[2]) * y;
ans += (a[3] - a[0] - a[1] - a[2]) * x;
} else {
i64 sum = a[0] + a[1] + a[2] + a[3];
ans += sum / 2 * y;
ans += (sum & 1ll) * x;
}
}
std::cout << ans << "\n";
}
D. 小L的字符串翻转
题意:给你一个01串,对于一个
如果一组中有1又有0,则必定使得长度加1,如果有
点击查看代码
void solve() {
int n;
std::cin >> n;
std::string s;
std::cin >> s;
std::vector<int> sum(n + 1);
for (int i = 0; i < n; ++ i) {
sum[i + 1] = sum[i] + (s[i] == '1');
}
int ans = 0;
for (int i = 1; i <= n; ++ i) {
int cnt = 1;
for (int j = 1; j <= n; j += i) {
int r = std::min(n, j + i - 1);
int one = sum[r] - sum[j - 1];
if (one != r - j + 1 && one != 0) {
++ cnt;
}
}
ans ^= cnt;
}
std::cout << ans << "\n";
}
E. 小L的井字棋
题意:一个
正解是分类讨论,我写的爆搜。
直接搜索枚举怎么下就行。
点击查看代码
void solve() {
using A = std::array<std::string, 3>;
A s;
int sum = 0;
for (int i = 0; i < 3; ++ i) {
std::cin >> s[i];
sum += std::count(s[i].begin(), s[i].end(), 'G');
}
auto check = [&](A s) -> bool {
for (int i = 0; i < 3; ++ i) {
if (s[i][0] == 'X' && s[i][1] == 'X' && s[i][2] == 'X') {
return true;
}
if (s[0][i] == 'X' && s[1][i] == 'X' && s[2][i] == 'X') {
return true;
}
}
if (s[0][0] == 'X' && s[1][1] == 'X' && s[2][2] == 'X') {
return true;
}
if (s[0][2] == 'X' && s[1][1] == 'X' && s[2][0] == 'X') {
return true;
}
return false;
};
auto dfs = [&](auto self, A s, int u, int flag, int cnt) -> bool {
if (cnt == 0) {
return check(s);
}
if (u == 0 && cnt >= 2 && flag) {
std::vector<std::pair<int, int>> a;
for (int i = 0; i < 3; ++ i) {
for (int j = 0; j < 3; ++ j) {
if (s[i][j] == 'G') {
a.push_back({i, j});
}
}
}
for (int i = 0; i + 1 < cnt; ++ i) {
auto & [x1, y1] = a[i];
for (int j = i + 1; j < cnt; ++ j) {
auto & [x2, y2] = a[j];
s[x1][y1] = s[x2][y2] = 'X';
if (self(self, s, u ^ 1, 0, cnt - 2)) {
return true;
}
s[x1][y1] = s[x2][y2] = 'G';
}
}
} else if (u == 0) {
for (int i = 0; i < 3; ++ i) {
for (int j = 0; j < 3; ++ j) {
if (s[i][j] == 'G') {
s[i][j] = 'X';
if (self(self, s, u ^ 1, flag, cnt - 1)) {
return true;
}
s[i][j] = 'G';
}
}
}
} else if (u == 1) {
bool flag = true;
for (int i = 0; i < 3; ++ i) {
for (int j = 0; j < 3; ++ j) {
if (s[i][j] == 'G') {
s[i][j] = 'L';
flag &= self(self, s, u ^ 1, flag, cnt - 1);
s[i][j] = 'G';
}
}
}
return flag;
}
return false;
};
if (dfs(dfs, s, 0, 1, sum)) {
std::cout << "Yes\n";
} else {
std::cout << "No\n";
}
}
F. 小L的抽卡
待补。
G. 小L的三元组
待补。
H. 小L的min-max问题
题意:给你一个数组,求每个子区间的
赛时一直以为是dp,搞半天没搞出来。
考虑枚举一段分成的区间,那么只需要求出它到前面和后面有多少种组成
设区间为
特判
点击查看代码
void solve() {
int n, k;
std::cin >> n >> k;
std::vector<int> a(n + 1);
for (int i = 1; i <= n; ++ i) {
std::cin >> a[i];
}
std::vector C(n + 1, std::vector<Z>(n + 1));
for (int i = 0; i <= n; ++ i) {
for (int j = 0; j <= i; ++ j) {
if (i == 0 || j == 0) {
C[i][j] = 1;
} else {
C[i][j] = C[i - 1][j] + C[i - 1][j - 1];
}
}
}
Z ans = 0;
for (int i = 1; i <= n; ++ i) {
int max = 0, min = 2e9;
for (int j = i; j <= n; ++ j) {
max = std::max(max, a[j]);
min = std::min(min, a[j]);
if (i == 1 && j == n) {
if (k == 1) {
ans += (Z)max * min;
}
} else if (i == 1 && k >= 2) {
ans += C[n - j - 1][k - 2] * max * min;
} else if (j == n && k >= 2) {
ans += C[i - 2][k - 2] * max * min;
} else if (k >= 3) {
ans += C[i + n - j - 3][k - 3] * max * min;
}
}
}
std::cout << ans << "\n";
}
I. 小L的数学题
题意:给你
考虑最后一步是开平方,那么
注意特判
点击查看代码
void solve() {
i64 n, m;
std::cin >> n >> m;
if (n == 0) {
if (m == 0) {
std::cout << "Yes\n";
} else {
std::cout << "No\n";
}
return;
}
if (m == 0) {
std::cout << "No\n";
return;
}
std::cout << "Yes\n";
}
J. 小L的汽车行驶问题
题意:汽车每秒有个操作,会影响速度,问
签到题。模拟即可。
点击查看代码
void solve() {
int n;
std::cin >> n;
std::string s;
std::cin >> s;
i64 ans = 0, k = 0;
for (auto & c : s) {
if (c == '0') {
k += 10;
ans += k;
} else if (c == '1') {
k = std::max(0ll, k - 5);
ans += k;
} else {
ans += std::max(0ll, k - 10);
}
}
std::cout << ans << "\n";
}
K. 小L的几何
题意:给你
实际是求
求勾股数的证明官方视频题解说的很清楚,这里直接给结论,枚举两个奇数
这题比较卡常,需要对点对hash一下。
点击查看代码
void solve() {
int n;
std::cin >> n;
std::unordered_set<i64> s;
std::vector<std::array<int, 3>> a(n);
auto get = [&](int x, int y) -> i64 {
return (i64)(x + 1000000) * 1000000 + y + 1000000;
};
for (int i = 0; i < n; ++ i) {
int x, y, r;
std::cin >> x >> y >> r;
a[i] = {x, y, r};
s.insert(get(x, y));
}
const int N = 4e5 + 5;
std::vector<std::vector<std::pair<int, int>>> R(N);
for (int i = 1; i < N; i += 2) {
for (int j = i + 2; j < N; j += 2) {
i64 a = (i64)i * j, b = ((i64)j * j - (i64)i * i) / 2, c = ((i64)i * i + (i64)j * j) / 2;
if (a >= N || b >= N || c >= N) {
break;
}
if (std::gcd(i, j) != 1) {
continue;
}
for (int k = 1; k * c < N; ++ k) {
R[k * c].push_back({a * k, b * k});
}
}
}
const int dx[] = {1, -1, -1, 1}, dy[] = {1, 1, -1, -1};
i64 ans = 0;
for (auto & [x, y, r] : a) {
if (r >= N) {
continue;
}
ans += s.count(get(x, y + r));
ans += s.count(get(x, y - r));
ans += s.count(get(x + r, y));
ans += s.count(get(x - r, y));
for (auto & [xd, yd] : R[r]) {
for (int i = 0; i < 4; ++ i) {
ans += s.count(get(x + dx[i] * xd, y + dy[i] * yd));
}
std::swap(xd, yd);
for (int i = 0; i < 4; ++ i) {
ans += s.count(get(x + dx[i] * xd, y + dy[i] * yd));
}
}
}
std::cout << ans << "\n";
}
L. 小L的构造
题意:求
我的做法是,特判
点击查看代码
void solve() {
int n;
std::cin >> n;
std::vector<std::array<int, 3> > a;
if (n <= 3) {
std::cout << 0 << "\n";
return;
}
if (n < 6) {
std::cout << 1 << "\n";
std::cout << 2 << " " << 3 << " " << 4 << "\n";
return;
}
for (int i = 1; i + 2 <= n; i += 3) {
a.push_back({i, i + 1, i + 2});
}
int m = a.size();
for (int i = 0; i + 1 < m; i += 2) {
std::swap(a[i][2], a[i + 1][0]);
}
if (m & 1) {
std::swap(a[m - 1][2], a[m - 2][2]);
}
std::cout << m << "\n";
for (auto & [x, y, z] : a) {
std::cout << x << " " << y << " " << z << "\n";
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具