CodeForces798cMike and gcd problem
Mike has a sequence A = [a1, a2, ..., an] of length n. He considers the sequence B = [b1, b2, ..., bn] beautiful if the gcd 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 index i (1 ≤ i < n), delete numbers ai, ai + 1 and put numbers ai - 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 sequence A beautiful if it's possible, or tell him that it is impossible to do so.
is the biggest non-negative number d such that d divides bi for every i (1 ≤ i ≤ n).
Input
The first line contains a single integer n (2 ≤ n ≤ 100 000) — length of sequence A.
The second line contains n space-separated integers a1, a2, ..., an (1 ≤ ai ≤ 109) — elements of sequence A.
Output
Output on the first line "YES" (without quotes) if it is possible to make sequence A 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 sequence A beautiful.
Example
2
1 1
YES
1
3
6 2 4
YES
0
2
1 3
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 than 1.
第一行一个n,代表n个数字输入,第二行输入数字,你可以对第i个数和第i+1执行一种交换操作,即用ai, ai + 1 替代ai - ai + 1, ai + ai + 1
求最少进行多少次操作,能使该序列的最大公共公因数>1,这里题目是绝对有解的,不需考虑no的情况
对于数字a,b进行操作: a,b a-b,a+b -2b,2a
由此题目就容易了,2是最容易想到的最大公因数,而进行操作又可以令无论奇偶的两个数都变成偶数
那么对数组进行访问
1.假如第i个数和第i+1个数都为偶数,操作次数为0(不产生影响,不用判断)
2.假如第i个数和第i+1个数都为奇数,操作次数为1
3.假如一个奇数一个偶数,操作次数为2
但这里就有一个问题了,2和3之间存在冲突,并且2几乎无法触发。而题目求的是最少操作数量,那么显然2是优于3的,所以在处理时应给2更高的优先级。因此可以对数组进行两次访问,第一次执行操作2,第二次执行操作3。
另外,题目有一个要注意的地方是在交换前最大公共公因数已经符合条件的话,可以直接结束,代码如下
#include<stdio.h> #define MAX 100000 int gcd(int s1,int s2) { int r; while (s2!=0) { r=s1%s2; s1=s2; s2=r; } return s1; } int main() { int n,i,j,a[MAX],t,ans; while(scanf("%d",&n)!=EOF) { t=0; for(i=1;i<=n;i++) { scanf("%d",&a[i]); } ans=gcd(a[1],a[2]); for(i=3;i<=n;i++) ans=gcd(ans,a[i]); if(ans>1) printf("YES\n0\n"); else { ans=0; for(i=2;i<=n;i++) { if(a[i-1]%2&&a[i]%2) { ans++; a[i-1]=0; a[i]=0; } } for(i=2;i<=n;i++) { if(a[i-1]%2==0&&a[i]%2||a[i-1]%2&&a[i]%2==0) { ans+=2; a[i-1]=0; a[i]=0; } } printf("YES\n%d\n",ans); } } }