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)。
 
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 }
View Code
 
原文地址:https://www.cnblogs.com/sxmcACM/p/3434262.html