1. 程式人生 > >892C Pride (n個數,求相鄰兩個數的最大公約數替換其中一個數,看要操作幾次使得n個數全部變成1)

892C Pride (n個數,求相鄰兩個數的最大公約數替換其中一個數,看要操作幾次使得n個數全部變成1)

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

.

Example 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,看有多少個1,若有num個1,那麼直接輸出n-num就行了;(2)就是

給出的序列中沒有1,那麼,看最先找到兩個數的最大公約數,用了幾次;要如何去找

在這解釋一下,我在程式碼中的我用的方法:問題一:為麼外層迴圈為n-1,問題二:為什麼內層迴圈為n-i,問題三:為什麼找相鄰的兩個數的最大公約數要賦予前一個 問題四:還當做操作一次;

問題一:為什麼外層迴圈為n-1,要是n的數的最大公約數都不為1,那麼這個序列就不會為1了,求n的數的最大公約數最多需要n-1次;

問題二:為什麼內層迴圈為n-i;舉個例子,求4個數的最大公約數,操作一次後(求任意相鄰的兩個數的最大公約數代替其中一個數),只需讓這兩個數的最大公約數,和其他數求最大公約數,這時候就剩3個數求最大公約數了

問題三:首先明確找的是相鄰兩個數的最大公約數,若相鄰兩個數的最大公約數等於1了就結束了,若不等於1,替換其中一個,在和相鄰數求gcd,對於一個數來說,它被替換成 和左邊的數的gcd,或和右邊數的gcd都一樣,舉個例子:2,6,9  任何相鄰兩個數的gcd都不為1,看6這個數的位置,它可以被替換成和2的gcd,再和9求gcd,或被替換成和9的gcd,再和2求gcd,你看看這兩種情況的結果是一樣吧;

問題四:為什麼找相鄰的兩個數的最大公約數要賦予前一個 ,還當做操作一次; 為什麼要當做一次 首先要明確

gcd(gcd(2,6),9) == gcd(gcd(2.6),gcd(6,9)); 為什麼 內層迴圈要迴圈遍歷;把每一個數都和相鄰的求一下gcd,看看那個數和相鄰的數 更快找到1;

程式碼:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define Max 2010
int n;
int a[Max];

int gcd(int c,int b)&
{
	if(b==0)
		return c;
	return gcd(b,c%b);
}
int main()
{
	int i,j;
	while(~scanf("%d",&n))
	{
		int num = 0;
		for(i=0;i<n;i++)
		{
			scanf("%d",&a[i]);
			if(a[i]==1) num ++;
		}
		if(num!=0)
		{
			printf("%d\n",n-num);
			continue;
		}
		int flag = 0;
		for(i=1;i<=n-1;i++)
		{
			for(j=0;j<n-i;j++)
			{
				a[j] = gcd(a[j],a[j+1]);
				if(a[j]==1)
				{
					printf("%d\n",i+n-1);
					flag = 1;
					break;
				} 
			}
			if(flag)
				break;
		}
		if(!flag)
			printf("-1\n");
	}
	return 0;
}