AtCoder Beginner Contest 416(A~D)
第一题:
题目:
思路:
给定一个字符串,判断区间 [L,R] 是否都为 'o'。(具体见代码注释)
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;const int N = 105;
char s[N];void solve() {int n, L, R;// 输入字符串长度、区间L和Rscanf("%d%d%d%s", &n, &L, &R, s + 1);int ok = 1;// 检查区间[L, R]是否全为'o'for (int i = L; i <= R; i++) {if (s[i] == 'x') {ok = 0;break;}}// 输出结果cout << (ok ? "Yes" : "No") << endl;
}int main() {solve();return 0;
}
第二题:
题目:
思路:
找出所有 '#' 位置,在 '#' 左右的 '.' 位置选一个放 'o'。(具体思路见注释)
代码:
#include <iostream>
#include <string>
using namespace std;
void solve() {string s, t; // s存储输入字符串,t存储构造的字符串cin >> s; // 输入原始字符串t = s; // 初始化构造字符串为原始字符串int n = s.size(); // 获取字符串长度int ok = 1; // 标记变量,控制'o'的放置// 遍历字符串,构造满足条件的新字符串for (int i = 0; i < n; i++) {if (s[i] == '.') { // 如果当前字符是'.'if (ok) { // 如果可以放置'o'ok = 0; // 放置'o'后,标记为不可放置t[i] = 'o'; // 修改当前位置为'o'}} else {ok = 1; // 如果遇到'#',重置标记为可放置}}cout << t << endl; // 输出构造的字符串
}int main() {solve(); // 调用solve函数处理问题return 0;
}
第三题:
题目:
思路:
用 dfs 暴力找出所有字符串,排序后取第 x 小的(具体见代码注释)
代码:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<string> a; // 存储所有可能的字符串组合
string s[10]; // 存储输入的字符串数组
int n, K, x; // n:字符串数量,K:组合长度,x:查询第x小的字符串
// 深度优先搜索生成所有可能的字符串组合
void dfs(string str, int cnt) {if (cnt == K) { // 当组合长度达到K时a.push_back(str); // 将当前组合加入结果集return;}// 递归生成所有可能的组合for (int i = 0; i < n; i++) {dfs(str + s[i], cnt + 1); // 拼接字符串并递归}
}
void solve() {cin >> n >> K >> x; // 输入参数// 输入n个字符串for (int i = 0; i < n; i++) {cin >> s[i];}dfs("", 0); // 从空字符串开始生成组合sort(a.begin(), a.end()); // 对所有组合进行排序cout << a[x - 1] << endl; // 输出第x小的字符串
}
int main() {solve(); // 调用solve函数处理问题return 0;
}
第四题:
题目:
思路:
累加 A、B 数组总和,贪心让 A、B 元素之和≥M 以减小结果,用 multiset 和二分查找实现。(具体见代码注释)
代码:
#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
typedef long long LL; // 使用长整型处理大数
const int N = 3e5 + 7; // 定义数组最大长度
int a[N], b[N]; // 存储输入的两个数组
void solve() {int n, m;scanf("%d%d", &n, &m); // 输入数组长度和模数LL ans = 0; // 初始化结果为// 输入数组a并累加总和for (int i = 0; i < n; i++) {scanf("%d", &a[i]);ans += a[i];}multiset<int> s; // 使用multiset存储数组b的元素// 输入数组b并累加总和,同时将元素加入multisetfor (int i = 0; i < n; i++) {scanf("%d", &b[i]);ans += b[i];s.insert(b[i]);}// 贪心策略:寻找最大的b[j]使得a[i]+b[j]≥m,从而减少总和for (int i = 0; i < n; i++) {auto it = s.lower_bound(m - a[i]); // 查找第一个大于等于m-a[i]的元素if (it != s.end()) { // 如果找到s.erase(it); // 从集合中移除该元素ans -= m; // 总和减去m}}cout << ans << endl; // 输出结果
}
int main() {int T;scanf("%d", &T); // 输入测试用例数量// 处理每个测试用例while (T--) {solve();}return 0;
}