Codeforces 798C Mike and gcd problem

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 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.

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 than 1.


题意: 给定一个数组,问最少变幻多少次可以把他变成一个漂亮数组。变幻方式说明:每个数组只能和与它相邻的数组一起进行变幻。例如:a[i],a[i+1]  ------> a[i] - a[i+1],a[i+1] + a[i],对漂亮数组的定义:整个数组的最大公约数大于1。

思路: 首先这个这个问题是不可能输出NO的,都是YES。然后,就是一些基本知识:1.任何数与0的最大公约数都是这个数本身。(确切的说是gcd值。)。2.而如果是负数, 那么可以把它转化成相反数来看。如果这个数组刚开始就是漂亮数组那么结果就是“0”,如果这个数组刚开始的是不是漂亮数组。然后,如果这个数组 初始中的最大公约数是1,那么最终变幻之后就只的最大公约数必然是2。然后,相邻的两个数是奇数那么变幻后就是 “奇数 - 奇数,奇数 + 奇数”。其中“奇数 - 奇数”是一个偶数,“奇数 + 奇数” 是偶数最大公约数中有2。如果是奇数与偶数相邻,则第一次变幻之后  “奇数 - 偶数,偶数 + 奇数”,(这两个数都是奇数,还需要在变幻一次才能得到两个偶数。)


基于这个思路接下来是我自己的AC代码:(个人感觉不是很好。)

#include<iostream>

#define MAX 100005
using namespace std;
int GCD(int a,int b)
{
	return b == 0 ? a : GCD(b,a%b);
}
int num[MAX];
int main( )
{
	int n;
	while(cin >> n){
		for(int j = 0; j < n; j++)
			cin >> num[j];
		int gcd = GCD(num[0],num[1]);
		for(int j = 2; j < n; j++)
			gcd = GCD(gcd,num[j]);
	//	cout << gcd << endl;
		if(gcd != 1){
			cout << "YES" << endl;
			cout << "0" << endl;
			continue;
		}
		int ans = 0;
		bool odd_ok;
		if((num[0]&1) == 0)
			odd_ok = false;
		else
			odd_ok = true;
		for(int j = 1; j < n; j++){
			if((num[j]&1) == 1){
				if(odd_ok)
					ans++,odd_ok = false;
				else
					odd_ok = true;
			}else{
				if(odd_ok)
					ans += 2,odd_ok = false;
				else
					odd_ok = false;
			}
		}
		if(odd_ok)
			ans += 2;
		cout << "YES" << endl;
		cout << ans << endl;
	}
}


然后,是另一份比较好的AC代码:

#include <bits/stdc++.h>
using namespace std;

int main ( ) {
	int n, ai, d = 0, ones = 0, ans = 0;
	scanf ( "%d", &n );
	for ( int i = 0; i <= n; ++i ) {
		if ( i == n ) ai = 0;
		else scanf ( "%d", &ai );
		d = __gcd(d,ai);
		if ( ai&1 ) ones++;
		else ans += ones/2 + 2*(ones%2), ones = 0;
	}
	printf ( "YES\n%d\n", d < 2 ? ans : 0 );
	return 0;
}


在这份代码的思路完全一样,只是相同的思路不一样的水平写出来的差距就是有那么大。


这个题刚开始的时候把题目理解错了,我以为这个最大公约数是只是相邻两个数之间的最大公约数。结果在我好不容易看懂题意之后感觉太后悔了。QAQ.......







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值