A
题意:就是你最多可以交换一次某两个元素, 尽可能的使得第i个位置是i的元素尽可能多, 问最多有多少个
思路:交换一次至少可以增加一个, 是增加一个还是两个判断一下就好
#include <cstdio>
const int qq = 1e5 + 10;
int num[qq];
int main(){
int n; scanf("%d", &n);
int cnt = 0;
for(int i = 0; i < n; ++i){
scanf("%d", num + i);
if(num[i] == i){
cnt++;
}
}
for(int i = 0; i < n; ++i){
if(num[i] == i) continue;
if(num[num[i]] == i){
printf("%d\n", cnt + 2);
return 0;
}
}
if (cnt != n) {
printf("%d\n", cnt + 1);
} else {
printf("%d\n", cnt);
}
}
B
题意:给出编号为1到3的原子的度数, 问 1-2 2-3 3-1 原子之间各有多少条线,
思路: 假设 1-2 , 2-3, 3-1,原子之间各有x, y, z根线, 则x + y = b, y + z = c, x + z = a, 那么我们可以枚举x, 根据a, b, c可以求出y, z, 判断y, z 是否合法就可以
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
const int qq = 1005;
const int N = 1e9 - 500;
int num[qq];
int main(){
int a, b, c; scanf("%d%d%d", &a, &b, &c);
int x, y, z;
for(int i = 0; i <= a; ++i){
x = i;
z = a - x;
y = c - z;
if(z < 0 || y < 0) continue;
if(x + y == b){
printf("%d %d %d\n", x, y, z);
return 0;
}
}
puts("Impossible");
return 0;
}
C
随便求一下就好
#include <cstdio>
const int qq = 1e5 + 10;
int num[qq];
int main(){
int n; scanf("%d", &n);
int cnt = 0;
int pre;
int x;
for(int i = 0; i < n; ++i){
if(i == 0){
scanf("%d", &pre);
cnt++;
continue;
}
scanf("%d", &x);
if(x == pre) continue;
pre = x;
cnt++;
}
printf("%d\n", cnt);
}
D
题意:你可以使得k个0 变成 1, 使得连续的1最多
思路: two point 维护每个合法区间, k = 0的情况直接特判掉了 暂时还没想到普遍性的解法
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
const int qq = 3e5 + 10;
int num[qq];
int main(){
int n, k; scanf("%d%d", &n, &k);
for(int i = 0; i < n; ++i) scanf("%d", num + i);
int maxn = -1;
int l, r, res, id;
l = r = res = 0;
if(k == 0){
for(int i = 0; i < n; ++i){
if(num[i] == 1) res++;
else res = 0;
maxn = max(res, maxn);
}
printf("%d\n", maxn);
for(int i = 0; i < n; ++i)
printf("%d ", num[i]);
puts("");
return 0;
}
while(r < n){
if(num[r] == 0){
if (k) {
k--;
} else {
while(num[l] != 0) l++;
l++;
}
}
if(maxn < r - l + 1){
maxn = r - l + 1;
id = l;
}
r++;
}
printf("%d\n", maxn);
for(int i = 0; i < n; ++i){
if (i >= id && i <= id + maxn -1) {
printf("%d ", 1);
} else {
printf("%d ", num[i]);
}
}
puts("");
return 0;
}
E
题意:你需要在两个gcd != 1 的数之间加一个数, 使得两个相邻数之间的gcd = 1
思路 : 找出接近1e9 的最大的三个素数, 然后按规则加就好
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
const int qq = 1005;
const int N = 1e9 - 500;
int num[qq];
int prime[5] = {999999893, 999999929, 999999937};
int gcd(int x, int y){
return y == 0 ? x : gcd(y, x % y);
}
int main(){
/*for(int i = N ; i <= 1000000000; ++i){
bool flag = true;
for(int j = 2; j <= sqrt(i) + 1; ++j)
if(i % j == 0){
flag = false;
break;
}
if (flag) {
printf("%d\n", i);
}
}*/
int n; scanf("%d", &n);
for(int i = 0; i < n; ++i) scanf("%d", num + i);
for(int i = 1; i < n; ++i){
if (gcd(num[i-1], num[i]) == 1) {
printf("%d ", num[i-1]);
} else {
printf("%d ", num[i-1]);
for(int j = 0; j < 3; ++j){
if(num[i-1] != prime[j] && num[i] != prime[j]){
printf("%d ", prime[j]);
break;
}
}
}
}
printf("%d\n", num[n-1]);
return 0;
}