Pride

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
Note
In the first sample you can turn all numbers to 1 using the following 5 moves:

[2, 2, 3, 4, 6].
[2, 1, 3, 4, 6]
[2, 1, 3, 1, 6]
[2, 1, 1, 1, 6]
[1, 1, 1, 1, 6]
[1, 1, 1, 1, 1]
We can prove that in this case it is not possible to make all numbers one using less than 5 moves.
问按照题目要求做多少次可以把所有的数字都变成1。本来以为是模拟,但是时间复杂度真的让人害怕,只得找规律。
①当原始序列中有1的时候,有多少个1,最后输出n-num(1的数量)就好了。
②原始序列没有1,这样的话就只能去按照题目的模拟了,只要是出现了1,就和第一种情况一样了,按着第一种情况,就是n-1次,但是还应该加上在出现1 之前的那几次操作。
代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;

const int maxx=1e4+10;
int a[maxx];
int n;

int gcd(int x,int y)
{
	if(y==0) return x;
	else return gcd(y,x%y);
 } 
int main()
{
	while(scanf("%d",&n)!=EOF)
	{
		int num=0;
		for(int i=0;i<n;i++)
		{
			scanf("%d",&a[i]);
			if(a[i]==1) num++;
		}
		if(num)
		{
			printf("%d\n",n-num);
			continue;
		}
		else 
		{
			int flag=0;
			for(int i=1;i<=n-1;i++)//要是n的数的最大公约数都不为1,那么这个序列就不会为1了,求n的数的最大公约数最多需要n-1次
			{
				for(int j=0;j<n-i;j++)//为什么内层循环为n-i;举个例子,求4个数的最大公约数,操作一次后(求任意相邻的两个数的最大公约数代替其中一个数),只需让这两个数的最大公约数,和其他数求最大公约数,这时候就剩3个数求最大公约数了
				{
					a[j]=gcd(a[j],a[j+1]);
					if(a[j]==1)
					{
						printf("%d\n",n+i-1);
						flag=1;
						break;
					}
				}
				if(flag) break;
			}
			if(!flag) printf("-1\n");
		}
	}
}

努力加油a啊,(o)/~

猜你喜欢

转载自blog.csdn.net/starlet_kiss/article/details/84580343