hdu1576(A/B)数论题==欧几里德 A/B
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1368 Accepted Submission(s): 1044
Problem Description
要求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)(我们给定的A必能被B整除,且gcd(B,9973) = 1)。
Input
数据的第一行是一个T,表示有T组数据。
每组数据有两个数n(0 <= n < 9973)和B(1 <= B <= 10^9)。
每组数据有两个数n(0 <= n < 9973)和B(1 <= B <= 10^9)。
Output
对应每组数据输出(A/B)%9973。
Sample Input
2
1000 53
87 123456789
Sample Output
7922
6060
Author
xhd
Source
题目分析:
参考我的博文中的欧几里德模板
解题方法:
(1)n=A%9973,则n=A-A/9973*9973。又A/B=x,则A=Bx。所以Bx-A/9973*9973=n。即Bx-9973y=n。
到这里我们可以发现:只要求出x的值,即可算出x%9973,也就是(A/B)%9973了。顺利解决了! gcd(a,b) = ax + by;
(2)题目关键转到如何求出x了。题目的输入是n和B,利用扩展欧几里德算法可求出gcd(B,9973)=Bx1+9973y1=1的x1。
等式两边同乘以n,得B(nx1)-9973(-ny1)=n。可知nx1就是Bx-9973y=n的解了!!!即x=nx1。
(3)对于第三部得到的x可能是负数,由题这显然是不正确的。
可以做这样的转化:(x%9973+9973)%9973(这可以想一下一个数除以另一数,反过来求这个数时你会怎样。。。提醒:数 = 除数×商+余数(即取模的数))
1 # include<iostream> 2 # include<cstdio> 3 using namespace std; 4 void extend(int a,int b,int &x,int &y) 5 //int extend(int a,int b,int &x,int &y) 6 { 7 if(b == 0) 8 { 9 x = 1; 10 y = 0; 11 return ; 12 //return a; 13 } 14 extend(b,a%b,x,y); 15 int temp = x; 16 x = y; 17 y = temp - (a/b)*y; 18 //return gcd; 19 } 20 int main() 21 { 22 int a,n,b,x,y; 23 int t; 24 cin>>t; 25 while(t--) 26 { 27 cin>>n>>b; 28 extend(b,9973,x,y); 29 x*=n; 30 a=(x%9973+9973)%9973; 31 cout<<a<<endl; 32 } 33 return 0; 34 }