题目:A/B
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4259 Accepted Submission(s): 3283
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
思路:
这道题的题意说的很清楚,就是一个关于整除的问题。
一开始的想法当然是对语言表达式进行数学表达式的转换。由n=A%9973,那么A=n+m*9973,而B又和9973互质,且要求的是(A/B)%9973的值,那么就可以变形为((n+m*9973)/B)%9973。
一开始的想法是遍历m求解,当第一个满足的时候结束遍历,但是这种做法的时间消耗太大,比如题目里给的第一个样例,m要遍历到10的6次方数量级才会结束,肯定会超时。
后来就想换一种思路,倒推回去。一个数模9973,所得数一定在0-9972之间,如果遍历结果的话会大大缩短遍历的时间。
所以不妨设结果为i,则表达式变为,((n+m*9973)/B)%9973=i,再变形得,((n+m*9973)/B)=i+9973*j,最后再移项得,n-B*i=B*j*9973-m*9973。所以若是i解的话一定满足n-B*i能被9973整除。由于n,B都是已知量,所以不妨让i从1到9973开始遍历,得到第一个符合的i值即为所求。
代码:
#include<iostream>
#include<stdio.h>
#include<cmath>
using namespace std;
int main()
{
int T;
cin>>T;
for(int i=0;i<T;i++)
{
long long B,n;
cin>>n>>B;
for(int i=1;i<=9972;i++)
{
long long x;
x=B*i-n;
if(x%9973==0)
{
cout<<i<<endl;
break;
}
}
}
}