For any two integers x and k there exists two more integers p and q such that:
It’s a fairly easy task to prove this theorem, so we’d not ask you to do that. We’d ask for something even easier! Given the values of x and k, you’d only need to find
integers p and q that satisfies the given equation
Input
The first line of the input contains an integer,T (1≤T≤1000) that gives you the number of test cases. In each of the followingT lines you’d be given two positive integers x and k. You can safely assume that x and k will always be less than 108.
Output
For each of the test cases print two integers:p and q in one line. These two integers are to be separated by a single space. If there are multiple pairs of p and q that satisfy the equation, any one would do. But to help us keep our task simple, please make sure that the values, and fit in a 64 bit signed integer.
3 5 2 40 2 24444 6 |
1 1 1 1 0 6
|
Problem setter: Monirul Hasan, Member of Elite Problemsetters' Panel
Special Thanks: Shahriar Manzoor, Member of Elite Problemsetters' Panel
首先是要证明一个方程必定有整数解
由扩展欧几里得知 ax+by=gcd(a,b); 为了方便令 g=gcd(a,b), 则ax+by=g 这样我们构造一个可行解(x1,y1),在得到一个可行解后就可以得到无数组解,他们是(x1-k*(b/g) , y1+k*(a/g)),(其中g=gcd(a,b),k是任意整数)
而对于方程ax+by=c,只要c是g的倍数那么就有整数解,否则没有。
看完原题,p对应的是x/k的下取整,q对应的是x/k的上取整,然后p*m+q*n=x,这个方程其实就是ax+by=c的形式,而且这个方程一定有整数解
因为d=gcd(p,q),若p=q,则d=p,若p!=q即|p-q|=1,则d=1,所以无论如何x一定是d的倍数,这个方程一定有整数解然后先用floor和ceil处理出p,q,然后 直接套模板去求解就可以了
可以这样思考: 对于a' = b, b' = a % b 而言,我们求得 x, y使得 a'x + b'y = Gcd(a', b') 由于b' = a % b = a - a / b * b (注:这里的/
是程序设计语言中的除法) 那么可以得到: a'x + b'y = Gcd(a', b') ===> bx + (a - a / b * b)y = Gcd(a', b') = Gcd(a, b) ===>
ay +b(x - a / b*y) = Gcd(a, b) 因此对于a和b而言,他们的相对应的p,q分别是 y和(x-a/b*y); p,q分别为ax+by=gcd(a,b)解出的x,y;
而我们的题是求ax+by=X的解,所以最后p与q再乘以X/gcd(a,b)
学会使用两个c语言的函数,floor取下整,ceil取上整
#include <cstdio>
#include <iostream>
#include <math.h>
using namespace std;
int exgcd(long long a,long long b,long long& x,long long& y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
else
{
int r=exgcd(b,a%b,x,y);
int t=x;
x=y;
y=t-a/b*y;
return r;
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
long long a,b,c,k,x,y;
cin>>c>>k;
a=floor(1.0*c/k); //取下整
b=ceil(1.0*c/k); //取上整
int d=exgcd(a,b,x,y);
x*=c/d;
y*=c/d;
cout<<x<<" "<<y<<endl;
}
return 0;
}