要求(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
方法一:
扩展欧几里得算法:参考:https://blog.youkuaiyun.com/yoer77/article/details/69568676
输入的n=A%9973(没有输入A),A%B=0(A必能被B整除),B与9973互素(GCD(B,9973)=1)。
解题过程首先是建立方程,然后才能编写程序。
设x=(A/B)%9973(x是最终想计算的值),则9973k+x=A/B(k为整数),得A=9973Bk+xB。
因为n=A%9973与A=9973Bk+xB,所以xB%9973=n,得xB=n+9973y。
故:(x/n)B+(-y/n)9973=1=GCD(B,9973),该方程有解。
要求x和y,先求X=x/n和Y=-y/n,即先解方程BX+9973Y=1。
最后,x=X*n。
需要注意的是,求得的x有可能是负值,需要进行调整。
代码如下:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll x,y;
void exgcd(ll a,ll b,ll &x,ll &y){
if(b==0){
x=1;
y=0;
return ;
}
exgcd(b,a%b,x,y);
ll t=y;
y=x-(a/b)*y;
x=t;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
ll n,b;
scanf("%lld %lld",&n,&b);
exgcd(b,9973,x,y);
x*=n;
printf("%lld\n",(x%9973+9973)%9973);
}
return 0;
}
方法二:
试探法:
输入的n=A%9973(没有输入A),A%B=0(A必能被B整除),B与9973互素(GCD(B,9973)=1)。
解题过程首先是建立方程,然后才能编写程序。
设x=(A/B)%9973(x是最终想计算的值,满足0<=x<=9972),则9973k+x=A/B(k为整数),得A=9973Bk+xB。
因为n=A%9973与A=9973Bk+xB,所以xB%9973=n,得xB=n+9973y,亦得xB-n=9973y。
故:(xB-n)%9973=0
代码如下:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
int main(){
int T;
scanf("%d",&T);
ll n,b,a=9973;
while(T--){
scanf("%lld %lld",&n,&b);
for(ll i=0;i<a;i++){
if((i*b-n)%a==0){
printf("%lld\n",i);
break;
}
}
}
return 0;
}