最大公因数的一个小性质

最大公因数存在以下的性质

设s = gcd(a,b),则s = gcd(xa+yb,ma+nb);
其中,x,y,m,n为正整数

这里我们通过一个程序来进行说明

#include<bits/stdc++.h>
#define ll long long
using namespace std;

ll aim[100];

ll gcd(ll a,ll b)
{
	if(a<b)return gcd(b,a);
	return (b==0)? a:gcd(b,a%b);
}

int main()
{
	aim[0]=28;
	aim[1]=56;
	for(int i=2;i<100;i++)
	{
		aim[i]=aim[i-1]+aim[i-2];
	}
	cout<<"We get the biggest common num is "<<gcd(aim[0],aim[1])<<endl;
	int a,b;
	cout<<"===============OK==============="<<endl;
	while(cin>>a>>b)
	{
		cout<<"You slect the num is "<<aim[a]<<" and "<<aim[b]<<endl;
		cout<<"So the biggest common num is "<<gcd(aim[a],aim[b])<<endl;
		cout<<"---------------"<<endl;
	}
	return 0;
}

上述程序其实是对已知的28,56按照斐波那契数列的原理进行计算

之后我们随意输入a,b来检验数组中a,b位置的两个数的最大公因数

输入几组后,我们发现其得到的结果均为gcd(a,b)

比如,输入数据

2 3
23 64
53 32
26 36

得到的结果如下

We get the biggest common num is 28
===============OK===============
2 3
You slect the num is 84 and 140
So the biggest common num is 28
---------------
23 64
You slect the num is 2100700 and 777780920988064
So the biggest common num is 28
---------------
53 32
You slect the num is 3908348148460 and 159680836
So the biggest common num is 28
---------------
26 36
You slect the num is 8898708 and 1094468732
So the biggest common num is 28
---------------
^Z

--------------------------------
Process exited after 8.104 seconds with return value 0

下面我我给出一个例题

官方给出的解题报告如下

Problem A

观察题目可知两个容器按照如下状态转移
(F1,F2)->(F2,F3)...(FN+1,FN+1+Y)

之后继续按FN=FN-1+FN-2递推,易知这个序列分成了两部分,1~FN和FN后面的

将后面的那个序列看成新的序列{A} 若求GCD(FM+1,FM+2

则是在求GCD(AM-N+1,AM-N+2

由更相减损术知:GCD(AM-N+2,AM-N+1)=GCD(AM-N+1,AM-N+2-AM-N+1)=GCD(AM-N+1,AM-N)...=GCD(A1,A2)

A1=FN+1
A2=FN+2+Y

M<70可以直接递推求解。

Std:

#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {
	if (b == 0)return a;
	else return gcd(b, a % b);
}
ll F[123];
ll b1,b2;

int main() {
	int t;
	int testCase = 0;
	cin >> t;
	while (t--) {
		ll x, n, y, m;
		cin >> x >> n >> y >> m;
		a[1] = 0, a[2] = x;
		for (int i = 3; i <= 72; i++) {
			F[i] = F[i - 1] + F[i - 2];
		}
		b1 = a[n + 1];
		b2 = a[n + 2]+y;
		printf("Case %d: %lld\n", ++testCase, gcd(b1, b2));
	}
}

OK

posted @ 2020-07-30 17:22  SavenNeer  阅读(288)  评论(0编辑  收藏  举报