CodeForces798C Mike and gcd problem(思路)

来源:互联网 发布:js保存cookie到本地 编辑:程序博客网 时间:2024/05/23 01:58

题意:给你一个整数序列a,每次操作把a[i],a[i+1]删除,用a[i] - a[i + 1]和a[i] + a[i + 1]替换,问最少多少次操作可以使序列a的最大公约数大于1?

思路:显然一定可以通过操作使a的gcd大于1。首先,先算一遍gcd,如果大于1,直接输出0。否则从头开始检查,如果a[i]为偶数不用变,因为偶数的最大公约数一定大于1,如果是奇数,再看a[i + 1]的奇偶性,如果a[i + 1]为奇数,则可通过一步操作使a[i]和a[i + 1]变为偶数;如果a[i + 1]为奇数,则可通过两步操作使a[i]和a[i + 1]为偶数。统计答案输出即可。

#include <cstdio>#include <algorithm>#include <iostream>#include<vector>#include<cmath>#include<set>#include<cstring>#include<map>using namespace std;typedef long long ll;const int maxn = 21e2 + 10;const int maxt = 100200;const int inf = 0x3f3f3f3f;const ll INF = 0x7f7f7f7f7f;const int mod = 1e9 + 7;const double pi = acos(-1.0);const double eps = 1e-8;int a[100010];int gcd(int x, int y){    return !y ? x : gcd(y, x % y);}int main(){   // printf("%d\n", gcd(0, 0));    int n;    scanf("%d", &n);    int g = 0;    int ans = 0;    for(int i = 0; i < n; ++i){        scanf("%d", &a[i]);        g = gcd(g, a[i]);    }    if(g > 1) printf("YES\n0\n");    else{        for(int i = 0; i < n; ++i){            if(a[i] == 0) continue;            if(a[i] % 2 && a[i + 1] % 2 == 0) ans += 2;            if(a[i] % 2 && a[i + 1] % 2){                ans++;                a[i + 1] = a[i] + a[i + 1];            }        }        printf("YES\n%d\n", ans);    }    return 0;}


1 0