URL:https://codeforces.com/contest/1814
目录
A
Problem/题意
给定 n 和 k,问是否存在 x 和 y,使得 2 * x + k * y = n。
Thought/思路
一开始以为要用扩展欧几里得,然后仔细一想发现,扩欧有解的条件就是 n 是 gcd(a, b) 的倍数,所以直接判断 n 能否整除 gcd(a, b) 即可。
Code/代码
#include "bits/stdc++.h"
#define int long long
signed main() {
int t; std::cin >> t;
while (t--) {
int n, k; std::cin >> n >> k;
if (n % std::__gcd(2ll, k) == 0) std::cout << "YES" << "\n";
else std::cout << "NO" <<"\n";
}
}
B
Problem/题意
一开始你在格子 (0, 0),步长 step = 1。
给出 (a, b),问最少几次操作能从 (0, 0) 到 (a, b)。
操作有:(设现在在格子(x, y))
1.移动到 (x + step, y)
2.移动到 (x, y + step)
3.将步长加一:step = step + 1
Thought/思路
一开始模拟了几个例子,又考虑了一下数据范围,就想到:每次移动都要从当前距离终点的横纵距离中,选一个共同的并且第一个 >= step 的因数来做下一次的步长。
但是WA了。
后来想到,既然最后一定是找到某个步长,使得距离最小,那其实就可以枚举这个步长,维护最小值即可。
Code/代码
#include "bits/stdc++.h"
int solve(int &a, int &b) {
int ans = 1e9;
for (int m = 1; m <= (int)1e5; ++ m) {
ans = std::min(ans, m - 1 + (a + m - 1) / m + (b + m - 1) / m);
}
return ans;
}
signed main() {
int t; std::cin >> t;
while (t --) {
int a, b; std::cin >> a >> b;
std::cout << solve(a, b) << "\n";
}
}
C
Problem/题意
有 n 种不同颜色的球,同种颜色的球放在一个盒子里面,一共放了 n 个盒子。
给出每种颜色的球,需要查找的次数 cnt[i],并且查找工作由两个 探路者(蒸鸡掰器人) 来做,探路者A查一个盒子需要 s1 秒,探路者B查一个盒子需要 s2 秒。
我们需要设置两个数组,分别由两个探路者在其中查找,问怎么安排这 n 个盒子,使得总查找时间最小。
注意:
找到目标盒子的查找时间,等于“他在数组中的位置 i * 探路者查一个盒子的时间 s”。
Thought/思路
显然要把 cnt 最大的盒子放在数组前面,那么具体放在哪个数组中呢?
假设 s1 = 3,s2 = 1,会有这么一个事实:
一个盒子 x,放在数组B的第三位,和放在数组A的第一位,代价是一样的。
因此,我们可以选择 s 小的数组来放一个盒子,并且要将这个 s += s,意味着在这个数组中的下一位,代价更大了。每次选择代价更小的数组,将盒子放进去即可。
Code/代码
#include "bits/stdc++.h"
struct node {
int id, cnt;
bool operator < (const node &t) const {
return cnt > t.cnt;
}
};
void solve() {
int n, s1, s2;
std::cin >> n >> s1 >> s2;
std::vector <node> r(n + 1);
for (int i = 1; i <= n; ++ i) {
std::cin >> r[i].cnt;
r[i].id = i;
}
std::sort(r.begin() + 1, r.end());
// for (int i = 1; i <= n; ++ i) std::cout << r[i].cnt << "\n";
std::vector <int> ans[2];
int c = s1, d = s2;
for (int i = 1; i <= n; ++ i) {
int j = i;
while (j <= n and c <= d) {
ans[0].push_back(r[j ++].id);
c += s1;
}
while (j <= n and d <= c) {
ans[1].push_back(r[j ++].id);
d += s2;
}
i = j - 1;
}
int a = ans[0].size(), b = ans[1].size();
std::cout << a;
for (int i = 0; i < a; ++ i) {
std::cout << " " << ans[0][i];
}
std::cout << "\n";
std::cout << b;
for (int i = 0; i < b; ++ i) {
std::cout << " " << ans[1][i];
}
std::cout << "\n";
}
signed main() {
int t; std::cin >> t;
while (t --) {
solve();
}
}