zoukankan      html  css  js  c++  java
  • codeforces#410C Mike and gcd problem

    题目:Mike and gcd problem

    题意:给一个序列a1到an ,如果gcd(a1,a2,...an)≠1,给一种操作,可以使ai和ai+1分别变为(ai+ai+1)和(ai-ai+1);问需要执行几次这个操作才能使得gcd(a1,a2,...an)>1.

    分析:

    1.首先,答案总是YES。

    2,假设gcd(a1,a2,...an)=1,在一次对ai和ai+1的操作后新的gcd为d,则d满足:d|ai - ai + 1 and d|ai + ai + 1  d|2ai and d|2ai + 1.。同样,因为d是新序列的gcd,所以d也满足: d|aj, j ≠ i, i + 1.

    3.从而我们得到:所以gcd(a1,a2,...an)=1,则在一次操作后,序列的gcd最多会变得两倍大.(即会变成2.)

    4.这意味着如果我们要是序列的gcd大于1的话只用使所有的数为偶数即可。

    5.因为两个奇数只通过一次操作即都可以变成偶数,而一奇一偶要通过两次才可以都变成偶数。

    6.可以把题目转化为:给一个序列a1到an ,如果gcd(a1,a2,...an)≠1,求将所有数变成偶数需要的操作次数 

    7.又可转化为:求序列中有几段连续为奇数,如果使奇数段中含的数为偶数个k,则需要k/2次,如果为奇数个,则需要(k/2)+2次;

    代码:

    /*
    Problem: C. Mike and gcd problem
    Time: 2017/5/5/19:21
    */
    
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<map>
    #include<vector>
    #define ll long long
    #define inf 100000000
    using namespace std;
    
    ll a[100005];
    ll gcd(ll a,ll b)
    {
        return b==0?a:gcd(b,a%b);
    }
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%I64d",a+i);
        ll d=a[0];
        for(int i=1;i<n;i++)
            d=gcd(d,a[i]);
        int ans=0;
        if(d<=1)
        {
            int odd=0;
            for(int i=0;i<n;i++)
            {
                if(a[i]%2!=0) odd++;
                else if(odd!=0)
                {
                    ans+=(odd%2==0?(odd/2):(odd/2+2));
                    odd=0;
                }
            }
            //cout<<ans<<endl;
            if(odd) ans+=(odd%2==0?(odd/2):(odd/2+2));
        }
        printf("YES
    ");
        printf("%d
    ",ans);
        return 0;
    }
    View Code

    补充:(关于DIVISIBILITY AND GREATEST COMMON DIVISORS)

    几个定理:

    1.. Let a, b ∈ Z with a|b. Then a|bc for any c ∈ Z.

    2. If a|b and b|c then a|c.

    3.If a|b and a|c then a|(br + cs) for every r and s in Z. In particular, if a|b and a|c then a|(b + c) and a|(b − c).

    4.For nonzero a and b in Z, there are x and y in Z such that (3.2) (a, b) = ax + by.

  • 相关阅读:
    RPC、HTTP、IDL
    秋招拿了7个offer,分享一些反思和经验
    “功能测试”到“测试开发”升级之路
    Github最全买房租房攻略,火了!
    王垠:怎样尊重一个程序员?
    为什么曾经优秀的人突然变得平庸?
    你这么努力,为什么能力提升还这么慢?
    打工人到什么状态,就可以离职了?
    怎样才能迅速晋升?
    如何做个优秀的经理?
  • 原文地址:https://www.cnblogs.com/tristatl/p/6814830.html
Copyright © 2011-2022 走看看