A. Binary Imbalance
题意:给你一个01串,每次选一个01或者一个10在他们中间插一个0进去,问能不能让0的个数大于1。
我们进行一次插入操作后,显然还可以继续操作,所以只要有0和1就一定可以。注意特判全0的情况。
点击查看代码
void solve() {
int n;
std::cin >> n;
std::string s;
std::cin >> s;
if (s.find('1') == s.npos || s.find('0') != s.npos) {
std::cout << "YES\n";
} else {
std::cout << "NO\n";
}
}
B. Getting Points
题意:一共n天,你要在n天获得m分,让自己不被开除。每过七天会增加一个任务,每天可以上课,上课可以加x分,做任务可以加y分,每天只能上一次课,一次课可以最多做两个任务,如果每天都去上课也可以不被开除。但你想让自己休息的天数最多。
先计算有多少任务可以做,那么优先上课做两个任务,这样可以得 cnt / 2 * (x + 2 * y)分,如果m小于等于这个就直接输出 max(0, n - $\lceil $$\frac{m}{x+2*y}$$ \rceil$),否则先看剩下还有没有一个单独的任务,做完所有任务后判断还需要上多少天课就行。
点击查看代码
void solve() {
i64 n, m, x, y;
std::cin >> n >> m >> x >> y;
i64 cnt = (n + 6) / 7;
if (cnt / 2 * (x + 2 * y) < m) {
m -= cnt / 2 * (x + 2 * y);
i64 ans = cnt / 2;
if (cnt & 1) {
m -= x + y;
++ ans;
}
ans += std::max(0ll, (m + x - 1) / x);
std::cout << std::max(0ll, n - ans) << "\n";
} else {
std::cout << std::max(0ll, n - (m + x + 2 * y - 1) / (x + 2 * y)) << "\n";
}
}
C. Insert and Equalize
题意:给你一个数组,你要加一个不在这个数组里的数\(a_{n+1}\)进去,然后选一个x(x > 0),然后每个数不断加x到每个数相等。问最少加多少次。
对a排序后,x就是所有 \(a_i\) - \(a_{i-1}\)的最大公约数,因为它要满足能从\(a_{n-1}\)变到\(a_n\)那么x是\(a_{n-1}\)-\(a_n\)的因子,\(a_{n-2}\)变到\(a_n\)的过程中肯定要经过\(a_{n-1}\), 所以x是\(a_{n-1}\)-\(a_{n-2}\)的因子,同理,他应该是所有 \(a_i\) - \(a_{i-1}\)的最大公约数。\(a_{n+1}\)选一个最大的不在a里的x的倍数就行。
点击查看代码
void solve() {
int n;
std::cin >> n;
std::vector<i64> a(n);
i64 max = -2e9;
std::set<i64> s;
for (int i = 0; i < n; ++ i) {
std::cin >> a[i];
s.insert(a[i]);
max = std::max(max, a[i]);
}
if (n == 1) {
std::cout << 1 << "\n";
return;
}
std::sort(a.begin(), a.end());
i64 d = 0;
for (int i = 1; i < n; ++ i) {
d = std::gcd(d, a[i] - a[i - 1]);
}
d = std::abs(d);
i64 an = max - d;
for (i64 i = max - d; ; i -= d) {
if (!s.count(i)) {
an = i;
break;
}
}
i64 ans = (max - an) / d;
for (int i = 0; i < n; ++ i) {
ans += (max - a[i]) / d;
}
std::cout << ans << "\n";
}
D. Robot Queries
感觉是要讨论变化后的坐标对称关系。不会。
待补。