UVA 10673 Play with Floor and Ceil (扩展欧几里德)

来源:互联网 发布:洛阳平安数据科技招聘 编辑:程序博客网 时间:2024/06/08 04:57

Theorem

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.

Sample Input                             Output for Sample Input

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;
}

0 0
原创粉丝点击