• Mike and gcd problem CodeForces


    题目链接

    比较棒的一道题,

    题意: 给你一个N个数的数组,让你用尽量少的操作使整个数组的gcd大于1,即gcd(a1 ,a2,,,,an) > 1

    如果可以输出YES和最小的次数,否则输出NO

    首先我们来看一下这个操作,

    如果对   a b 老两个数进行操作

    第一次为 a-b a+b

    第二次为 -2b  2a

    由此可见,任何两个数最多进行两次操作,可以让他们都能被2整除。

    所以也就没有NO的情况。

    那么我们只需要预处理一下gcd,如果>1了,直接输出0次。

    gcd=1的话,那么就需要我们去处理这个字符串了。又上边的推导可见,我们以gcd=2为目标去实现是最优解。

    我们进入循环,找到一个a[i] 是odd的话,我们就和a[i+1] 进行处理,然后记录操作的次数,以此处理整个数组。

    最终得出答案。

    其他的一些题解讲到要先处理两个一起的odd再处理和even一起的odd,

    我实在不懂为什么要这么分优先级,直接一个for遇到odd就去处理就可以是最优解,无语多虑。

    具体细节请看代码:

    my code :

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb std::ios::sync_with_stdio(false)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define gg(x) getInt(&x)
    using namespace std;
    typedef long long ll;
    inline void getInt(int* p);
    const int maxn=1000010;
    const int inf=0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    int n;
    ll a[maxn];
    ll gcd(ll a,ll b)
    {
        return b?gcd(b,a%b):a;
    }
    int main()
    {
        gg(n);
        ll x=0ll;
        repd(i,1,n)
        {
            scanf("%lld",&a[i]);
            x=gcd(x,a[i]);
        }
        if(x>1)
        {
            printf("YES
    ");
            printf("0
    ");
        }else
        {
            ll ans=0ll;
            repd(i,1,n)
            {
                while(a[i]%2!=0)
                {
                    ans++;
                    if(i!=n)
                    {
                        ll y1=a[i];
                        ll y2=a[i+1];
                        a[i]=y1-y2;
                        a[i+1]=y1+y2;
                    }else
                    {
                        ll y1=a[i-1];
                        ll y2=a[i];
                        a[i-1]=y1-y2;
                        a[i]=y1+y2;
                    }
                }
            }
            printf("YES
    ");
            printf("%lld
    ",ans);
    
        }
    
        return 0;
    }
    
    inline void getInt(int* p) {
        char ch;
        do {
            ch = getchar();
        } while (ch == ' ' || ch == '
    ');
        if (ch == '-') {
            *p = -(getchar() - '0');
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 - ch + '0';
            }
        }
        else {
            *p = ch - '0';
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 + ch - '0';
            }
        }
    }
    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    JUC原子类 1
    线程优先级和守护线程
    多线程中断
    关于html5不支持frameset的解决方法
    shell中$0,$?,$!等的特殊用法
    Linux GCC常用命令
    C/C++中extern关键字详解
    js实现iframe自适应高度
    java线程安全总结
    Linux平台Java调用so库-JNI使用例子
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/10230548.html
Copyright © 2020-2023  润新知