Codeforces Round #410 (Div. 2)
A B略..A没判本来就是回文WA了一次gg
C.Mike and gcd problem
题意:一个序列每次可以把(a_i, a_{i+1})换成(a_i-a_{i+1},a_i+a_{i+1}),最小次数使gcd不为1
题解:
玩一下发现:
- 奇数 奇数 ( ightarrow) 偶数 偶数
- 奇数 偶数 $ ightarrow$ 奇数 奇数 ( ightarrow) 偶数 偶数
最后都变成偶数好像就是最优啊,贪心变就行了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=1e5+5;
inline int read(){
char c=getchar(); int x=0,f=1;
while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
return x*f;
}
int n, a[N], d;
int gcd(int a, int b) {return b == 0 ? a : gcd(b, a%b);}
int main() {
// freopen("in", "r", stdin);
n=read(); d = a[1] = read();
for(int i=2; i<=n; i++) a[i] = read(), d = gcd(d, a[i]);
if(d > 1) {puts("YES
0"); return 0;}
for(int i=1; i<=n; i++) a[i] = a[i] & 1;
int ans = 0;
for(int i=1; i<=n; i++) if(a[i]) {
if(a[i+1]) ans++, a[i] = a[i+1] = 0;
else ans += 2, a[i] = 0;
}
printf("YES
%d", ans);
}
D.Mike and distribution
题意:选(lfloor frac{n}{2} floor+1)个数满足(2*S_a > sum_a)和(2*S_b>sum_b)
题解:
竟然没想出贪心。注意两点
- b每相邻两个数选较大值,最后一定>一半
- 选(lfloor frac{n}{2} floor+1)个数,a排序后即使每相邻两个数选了较小值,再选一个最大的a根据坐标轴投影证明也可以>一半
比赛时想过随机但是没写,没想到真的能过,很难构造唯一解
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N = 1e5+5;
inline int read(){
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
int n, c[N];
struct meow{
int a, b, id;
operator < (const meow &r) const {return a > r.a;}
} a[N];
int main() {
//freopen("in", "r", stdin);
n=read();
for(int i=1; i<=n; i++) a[i].a = read();
for(int i=1; i<=n; i++) a[i].b = read(), a[i].id = i;
sort(a+1, a+1+n);
printf("%d
", n/2+1);
for(int i=1+(n&1); i<n; i+=2) {
if(a[i].b > a[i+1].b) c[a[i].id] = 1;
else c[a[i+1].id] = 1;
}
if(n&1) c[a[1].id] = 1;
else c[a[1].id] = c[a[2].id] = 1;
for(int i=1; i<=n; i++) if(c[i]) printf("%d ", i);
}