Codeforces 798C Mike and gcd problem【思维+贪心】好题!

探讨通过特定操作使数列的各元素最大公约数大于1的方法及最小步骤。分析不同数对的操作次数,并提出解决策略。

C. Mike and gcd problem
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Mike has a sequence A = [a1, a2, ..., an] of lengthn. He considers the sequence B = [b1, b2, ..., bn] beautiful if thegcd of all its elements is bigger than 1, i.e. .

Mike wants to change his sequence in order to make it beautiful. In one move he can choose an indexi (1 ≤ i < n), delete numbersai, ai + 1 and put numbersai - ai + 1, ai + ai + 1 in their place instead, in this order. He wants perform as few operations as possible. Find the minimal number of operations to make sequenceA beautiful if it's possible, or tell him that it is impossible to do so.

is the biggest non-negative numberd such that d dividesbi for everyi (1 ≤ i ≤ n).

Input

The first line contains a single integer n (2 ≤ n ≤ 100 000) — length of sequenceA.

The second line contains n space-separated integersa1, a2, ..., an (1 ≤ ai ≤ 109) — elements of sequence A.

Output

Output on the first line "YES" (without quotes) if it is possible to make sequenceA beautiful by performing operations described above, and "NO" (without quotes) otherwise.

If the answer was "YES", output the minimal number of moves needed to make sequenceA beautiful.

Examples
Input
2
1 1
Output
YES
1
Input
3
6 2 4
Output
YES
0
Input
2
1 3
Output
YES
1
Note

In the first example you can simply make one move to obtain sequence [0, 2] with .

In the second example the gcd of the sequence is already greater than1


题目大意:

我们有一种操作,选择两个相邻的数(Ai,Ai+1)能够将其变成:(Ai-Ai+1,Ai+Ai+1);

我们希望最终的数组的|Gcd(A1,A2,A3,A4,A5..............)|>1.询问最少需要操作多少步。


思路:


问题的操作是在两个数的基础上进行的。

那么我们不妨只考虑两个数的操作,手写几组数据不难发现,所有写出来的两个数A.B,都会在至多两次操作内完成任务。那么我们可以考虑其性质:

两个数A.B.无非四种情况:
奇数,奇数--------------->操作后变成       偶数,偶数

奇数,偶数--------------->操作后变成       奇数,奇数

偶数,奇数--------------->操作后变成       奇数,奇数

偶数,偶数--------------->操作后变成       偶数,偶数


所以:

如果原来两个数都是偶数的话,那么操作数为0.

如果原来两个数都是奇数的话,那么操作数为1.

如果原来两个数是一奇一偶的话,那么操作数为2.


而后我们考虑结果,其最终可行解为两种情况:

①偶数 偶数的话,那么没有什么异议.

②奇数 奇数的话,只有这两个数相等且>1的话才会满足结果。

其一定不会出现结果是(3 ,6)这种情况的,除非原序列就是这样的。



那么我们不妨将问题推展到三个数,如果结果是(奇数 奇数 奇数)的话,我们肯定原来序列和结果序列是一样的,而且这三个奇数是相等且大于1的。

否则不可能有这样的结果,反之,如果结果是(偶数 偶数 偶数)的话,那么是没有异议的。

所以如果原序列的结果是>1的,那么操作数需要为0.

反之我们将原序列全部变成偶数即可。


Ac代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
int gcd(int x,int y)
{
    return y==0?x:gcd(y,x%y);
}
int a[1500000];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i=0;i<n;i++)scanf("%d",&a[i]);
        int gc=0;
        for(int i=0;i<n;i++)gc=gcd(gc,a[i]);
        if(gc>1)
        {
            printf("YES\n0\n");
        }
        else
        {
            printf("YES\n");
            int output=0;
            for(int i=0;i<n-1;i++)
            {
                while(abs(a[i])%2==1)
                {
                    output++;
                    int tmp=a[i];
                    a[i]=a[i]-a[i+1];
                    a[i+1]=tmp+a[i+1];
                }
            }
            while(abs(a[n-1])%2==1)
            {
                output++;
                int tmp=a[n-2];
                a[n-2]=a[n-2]-a[n-1];
                a[n-1]=tmp+a[n-1];
            }
            printf("%d\n",output);
        }
    }
}










评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值