杭电1014—判断两个数互质
http://acm.hdu.edu.cn/showproblem.php?pid=1014
Uniform Generator
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K(Java/Others)
Total Submission(s): 18468 Accepted Submission(s): 7242
Problem Description
Computer simulations often requirerandom numbers. One way to generate pseudo-random numbers is via a function ofthe form
seed(x+1) = [seed(x) + STEP] % MOD
where '%' is the modulus operator.
Such a function will generate pseudo-random numbers (seed) between 0 and MOD-1.One problem with functions of this form is that they will always generate thesame pattern over and over. In order to minimize this effect, selecting theSTEP and MOD values carefully can result in a uniform distribution of allvalues between (and including) 0 and MOD-1.
For example, if STEP = 3 and MOD = 5, the function will generate the series ofpseudo-random numbers 0, 3, 1, 4, 2 in a repeating cycle. In this example, allof the numbers between and including 0 and MOD-1 will be generated every MODiterations of the function. Note that by the nature of the function to generatethe same seed(x+1) every time seed(x) occurs means that if a function willgenerate all the numbers between 0 and MOD-1, it will generate pseudo-randomnumbers uniformly with every MOD iterations.
If STEP = 15 and MOD = 20, the function generates the series 0, 15, 10, 5 (orany other repeating series if the initial seed is other than 0). This is a poorselection of STEP and MOD because no initial seed will generate all of thenumbers from 0 and MOD-1.
Your program will determine if choices of STEP and MOD will generate a uniformdistribution of pseudo-random numbers.
Input
Each line of input will contain a pairof integers for STEP and MOD in that order (1 <= STEP, MOD <= 100000).
Output
For each line of input, your programshould print the STEP value right- justified in columns 1 through 10, the MODvalue right-justified in columns 11 through 20 and either "GoodChoice" or "Bad Choice" left-justified starting in column 25.The "Good Choice" message should be printed when the selection ofSTEP and MOD will generate all the numbers between and including 0 and MOD-1when MOD numbers are generated. Otherwise, your program should print themessage "Bad Choice". After each output test set, your program shouldprint exactly one blank line.
Sample Input
35
1520
6392399999
Sample Output
3 5 Good Choice
15 20 Bad Choice
63923 99999 Good Choice
看完题目,立马觉得认出是判断STEP,MOD互质。于是百度搜索学习了欧几里得算法中关于互质的研究。
其计算原理依赖于下面的定理:
定理:gcd(a,b) =gcd(b,a mod b) (a>b 且a mod b 不为0)
证明:a可以表示成a = kb +r,则r = a mod b
假设d是a,b的一个公约数,则有
d|a,d|b,而r = a - kb,因此d|r
因此d也是(b,a mod b)的公约数
因此(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等,得证
或:证明:
第一步:令c=gcd(a,b),则设a=mc,b=nc
第二步:根据前提可知r =a-kb=mc-knc=(m-kn)c
第三步:根据第二步结果可知c也是r的因数
第四步:可以断定m-kn与n互素【否则,可设m-kn=xd,n=yd,(d>1),则m=kn+xd=kyd+xd=(ky+x)d,则a=mc=(ky+x)dc,b=nc=ycd,故a与b最大公约数≥cd,而非c,与前面结论矛盾】
从而可知gcd(b,r)=c,继而gcd(a,b)=gcd(b,r),得证
以上两种方法实质一样的。
其C语言描述如下:
intgcd(int a,int b)
{
if(b==0)returna;
elsereturn gcd(b,a%b);
}//递归法求最大公约数,当最大公约数是1的时候,两个数互质
if(gcd(x,y)==1)那么x,y互质
于是利用辗转相除法,程序如下:
#include<iostream>
#include<cstdio>
using namespace std;
int gcd(int a,int b)
{
if(b==0)return a;
else return gcd(b,a%b);
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
if(gcd(n,m)==1)
printf("%10d%10d Good Choice\n",n,m);
else
printf("%10d%10d Bad Choice\n",n,m);
}
return 0;
}
程序运行结果:
此外判断互质数还有一种简单的方法—减除法。如255与182。
255-182=73,观察知73<182。
182-(73×2)=36,显然 36<73。
73-(36×2)=1,
(255,182)=1。
所以这两个数是互质数。具体编程实现这里不再赘述。