Codeforces Round #741 (Div. 2)
A
显然,如果可以存在一个 \(x\) 使 \(r \equiv x - 1 \pmod x\),\(x - 1\) 为最优解。如果 \(2l - 1 \leq r\),显然答案为 \(\lfloor \frac{r - 1}{2} \rfloor\);否则,显然答案为 \(r \bmod l\)。
代码:
#include <stdio.h>
int main(){
int t;
scanf("%d", &t);
for (int i = 1; i <= t; i++){
int l, r;
scanf("%d %d", &l, &r);
if (l * 2 - 1 <= r){
printf("%d\n", (r - 1) / 2);
} else {
printf("%d\n", r % l);
}
}
return 0;
}
B
大胆猜想:答案只可能为 \(1\) 或 \(2\) 位不必证明。
代码:
#include <stdio.h>
#include <math.h>
int a[57];
inline bool is_prime(int n){
if (n < 2) return false;
if (n == 2) return true;
if (n % 2 == 0) return false;
int t = sqrt(n);
for (int i = 3; i <= t; i++){
if (n % i == 0) return false;
}
return true;
}
int main(){
int t;
scanf("%d", &t);
for (int i = 1; i <= t; i++){
int k, ansa, ansb;
bool flag = false;
scanf("%d", &k);
for (int j = 1; j <= k; j++){
scanf("%1d", &a[j]);
if (!flag && ((a[j] != 2 && a[j] % 2 == 0) || a[j] == 1 || a[j] == 9)){
ansa = 1;
ansb = a[j];
flag = true;
}
}
if (!flag){
for (int j = 1; j < k; j++){
for (int x = j + 1; x <= k; x++){
int t = a[j] * 10 + a[x];
if (!is_prime(t)){
ansa = 2;
ansb = t;
goto END;
}
}
}
}
END: printf("%d\n", ansa);
printf("%d\n", ansb);
}
return 0;
}
C
显然,\(0\) 对我们构造非常有用,因为 \(0\) 接在一坨数字前面或后面都可以构造出合法解。
特判全是 \(1\) 的情况即可。
代码:
#include <stdio.h>
#include <stdbool.h>
int a[20007];
int main(){
int t;
scanf("%d", &t);
for (int i = 1; i <= t; i++){
int n, m, pos;
bool flag = false;
scanf("%d", &n);
m = n / 2;
for (int j = 1; j <= n; j++){
scanf("%1d", &a[j]);
if (!flag && j > m && a[j] == 0){
pos = j;
flag = true;
}
}
if (flag){
printf("1 %d 1 %d\n", pos, pos - 1);
} else {
m = n - m;
for (int j = 1; j <= m; j++){
if (a[j] == 0){
pos = j;
flag = true;
break;
}
}
if (flag){
printf("%d %d %d %d\n", pos, n, pos + 1, n);
} else {
printf("1 %d 2 %d\n", n - 1, n);
}
}
}
return 0;
}
D1
显然需要预处理前缀和。
如果已经满足条件,显然答案为 \(0\);如果区间长度为奇数,答案为 \(1\);否则,答案为 \(2\)。
证明:设原本的值为 \(sum\),删掉的数对最终答案的贡献为 \(\pm 1\),并使其后面部分所有数的贡献反转,即后面的贡献取相反数,于是原问题转化为证明一定存在一个位置使左两部分原贡献相等。每个数对答案贡献为 \(\pm 1\),那么贡献将会是连续变化的,能取到 \(s\) 就一定能取到 \(\frac{s}{2}\)(上 / 下取整看原数的权值),得证。
代码:
#include <stdio.h>
int sum[300007];
char s[300007];
int main(){
int t;
scanf("%d", &t);
for (int i = 1; i <= t; i++){
int n, q;
scanf("%d %d", &n, &q);
scanf("%s", &s[1]);
for (int j = 1, k = 1; j <= n; j++, k = -k){
sum[j] = sum[j - 1] + k * (s[j] == '+' ? 1 : -1);
}
for (int j = 1; j <= q; j++){
int l, r;
scanf("%d %d", &l, &r);
if (sum[r] - sum[l - 1] == 0){
printf("0\n");
} else if ((r - l + 1) % 2 == 1){
printf("1\n");
} else {
printf("2\n");
}
}
}
return 0;
}

浙公网安备 33010602011771号