codeforces A.pride 数学题 gcd

题目大意:给你一个序列,每次可以选两个相邻的数,取最大公约数,然后将最大公约数替换其中一个数。问最少操作几次可以将所有数都变为1。

思路:要求最少操作,只需要求出最短的公共的gcd为一的区间的长度,几个例子,如果有a,b,c,d,e,f,g这7个数,

第一轮可以枚举gcd(a,b),gcd(b,c),gcd(c,d),gcd(d,e),gcd(e,f),gcd(f,g),

第二轮可以枚举gcd(a,b,c),gcd(b,c,d),gcd(c,d,e),gcd(d,e,f),gcd(e,f,g),

第三轮可以枚举gcd(a,b,c,d),gcd(b,c,d,e),gcd(c,d,e,f),gcd(d,e,f,g),

第四轮可以枚举gcd(a,b,c,d,e),gcd(b,c,d,e,f),gcd(c,d,e,f,g),

第五轮可以枚举gcd(a,b,c,d,e,f),gcd(b,c,d,e,f,g),

第六轮可以枚举gcd(a,b,c,d,e,f,g),

顺序执行每一轮,如果其中某一轮中gcd为1,则总操作数为n+轮数-1。

如果数组中原先有1,则另外考虑。

#include<cstdio>
#include<cstring>
#include<iostream>
#define maxn 2005
#define LL long long
#define mod 1000000007
using namespace std;
LL gcd(LL a,LL b)
{
	if(b==0)
		return a;
	return gcd(b,a%b);
}
int main()
{
	ios::sync_with_stdio(false);
	int n;
	int a[maxn];
	while(cin>>n)
	{
		int sum=0;
		for(int i=0;i<n;i++)
		{
			cin>>a[i];
			if(a[i]==1)
				sum++;
		}
		int cur;
		cur=a[0];
		for(int i=1;i<n;i++)
		{
			cur=gcd(cur,a[i]);
		}
		if(cur!=1)
		{
			cout << -1 << endl;
			continue;
		}
		if(sum!=0)
		{
			cout << n-sum << endl;
			continue;
		}
		int flag,ans;
		flag=0;
		for(int i=1;i<n;i++)
		{
			for(int j=0;j<n-i;j++)
			{
				a[j]=gcd(a[j],a[j+1]);
				if(a[j]==1)
				{
					ans=n+i-1;
					flag=1;
					break;
				}
			}
			if(flag)
				break;
		}
		cout << ans << endl;
	}	
	return 0;	
} 




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值