山师训练赛——FFFFFunctions

题目链接

其实这个题不是很难,但是我依然WA了23次(哭)
这个题目总的来说就是涉及到了gcd以及函数的递归调用。我WA的原因就是在于对题目给出的第一个函数没有优化,所以一直在RE(我还一直以为是数组的问题,害)
下面简单说一下gcd的推导过程:gcd也就是求最大公约数,在这里我们用到了辗转相除法也就是说gcd(a,b)=gcd(b,a%b),证明如下:

假设a=kb+r,其中k和r分别为a除以b后得到的商和余数。
则有r=a-kb
设d为a和b的一个公约数,那么由r=a-kb,得d也是r的一个约数
因此d是b和r的一个公约数
又由r=a%b,得d为b和a%b的一个公约数
因此d既是a和b的公约数,也是b和a%b的公约数
由d的任意性,得a和b的公约数都是b和a%b的公约数
由a=kb+r,同理可证b和a%b的公约数都是a和b的公约数

题目中所给的第一个函数是最原始的辗转相除法,即以减法的形式实现除法的效果。
AC代码:

#include<stdio.h>
#include<math.h>
long long a[1000010];
int p[1000010];
long long f(long long x,long long y)
{
	if(y==0) return x;
	else if(y==1||x==1) return 1;
	else return f(y,x%y); 
}

int main( )
{
	long long n; 
	while(scanf("%lld",&n)!=EOF){
	if(n==0)
	continue; 

	for(long long i=1;i<=n;i++)
	scanf("%lld",&a[i]);
	
	for(int i=1;i<=n;i++)
	scanf("%d",&p[i]);
	
	long long count=a[p[1]]; 
	for(int k=2;k<=n;k++)
		{
			count=f(count,a[p[k]]);
		}
	printf("%lld\n",count);
	} 
	return 0;
}
发布了21 篇原创文章 · 获赞 1 · 访问量 299

猜你喜欢

转载自blog.csdn.net/qq_44722533/article/details/103556830
今日推荐