Pride -codeforces 892C

题目

You have an array a with length n, you can perform operations. Each operation is like this: choose two adjacent elements from a, say x and y, and replace one of them with gcd(x, y), where gcd denotes the greatest common divisor.

What is the minimum number of operations you need to make all of the elements equal to 1?

Input

The first line of the input contains one integer n (1 ≤ n ≤ 2000) — the number of elements in the array.

The second line contains n space separated integers a1, a2, ..., an (1 ≤ ai ≤ 109) — the elements of the array.

Output

Print -1, if it is impossible to turn all numbers to 1. Otherwise, print the minimum number of operations needed to make all numbers equal to 1.

Examples

Input

5
2 2 3 4 6

Output

5

Input

4
2 4 6 8

Output

-1

Input

3
2 6 9

Output

4

题目大意 :

输入一串数字

然后找相邻两个数字的最大公约数,来替换掉其中一个。通过这样的方法来使这一串数字全部变成1

如果可以那么输出变化次数,如果不可以那么输出-1

算法

 没有什么算法

代码

#include<iostream>
using namespace std;
int gcd(int c,int b)                  //递归求最大公约数 
{
	if(b==0)
		return c;
	return gcd(b,c%b);
}                     
int main()
{
	int n,i,j,temp,sub,ans=1000000,sum=0;
	cin>>n;
	int a[n+1];               
	for(i=1;i<=n;i++)               //输入 
	{
		cin>>a[i];
		if(a[i]==1) sum++;      
	}                           
	if(sum!=0)
	{
		cout<<n-sum<<endl;
		return 0;
	}                             //如果这一串数字中含1,那么可以直接输出结果 
	 
	for(i=1;i<=n-1;i++)
	{
		temp=a[i];sub=1000000;
		for(j=i+1;j<=n;j++)
		{
			temp=gcd(temp,a[j]);      //temp每一步都更新 ,每一次求得相邻两个数的最大公约数,就把他赋值给两个中的后一个 
			if(temp==1)  
			{
				sub=j-i;             //一旦最大公约数是一,那么就可以转换为全唯一的数列,那么继续比较操作次数 
				break;
			}
		}
		ans=min(sub+n-1,ans);        //求最小的操作次数 
	}
	if(ans<1000000) cout<<ans<<endl; //如果这个操作次数比1000000小了,说明前面的循环找到了可以改变的方案,并对ans进行了赋值 
	else cout<<"-1"<<endl;

	return 0;
}

解析

首先要清楚,这一串数字中只要出现了 1,那么他肯定可以转换为全为一的序列,操作次数是n-1。(n=数列长度)

所以在输入的时候就计算等于1的元素个数,一但sum不是0,那么就说明存在,直接输出 return 0。

其次,两重循环,找一个区间,使这个区间的头尾最大公约数为1,具体点说是,使这个区间经过 |区间长度|次操作后,出现了数字1(因为一旦出现1就可以直接输出结果)。 

这两重循环中,temp一开始取a[i],之后不断变化为gcd(temp,a[j]),其实就是每一次求得相邻两个数的最大公约数,就把他赋值给两个中的后一个。  这个时候就会有人问 为什么要把最大公约数赋值给后一个,而不是前一个呢 (一会告诉你

一旦求出这个最短出现1的区间,那么结果就是 区间长度+n-1

最大公约数赋值给前一个还是后一个:

举个例子:2,6,9  任何相邻两个数的gcd都不为1,看6这个数的位置,它可以被替换成和2的gcd,再和9求gcd,或被替换成和9的gcd,再和2求gcd,结果是一样的,都是1

一开始我也搞不懂 后来看来别人的博客

猜你喜欢

转载自blog.csdn.net/baidu_41907100/article/details/84566079