uva10673floor and cei扩展的欧几里得
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=85482#problem/D
题意: 输入x和k,输出p和q。
思路:扩展的欧几里得。系数只差1,故最大公约数一定是1,最后得出ax+by=1的形式,而题目中等式右面不为1,那么等式右边是几就将等式左右同乘几,即将得出的x,y同乘几,得出最后的结果。
知识:
typedef long long ll;
void f(ll a,ll b,&ll g,&ll x,&ll y)
{
if(!b){g=a;x=1;y=0;}
else {f(b,a%b,g,y,x);y-=a/b*x;}
}
将除数传给被除数,余数传给除数,这是辗转相除法;最后的边界语句中g=a,因为当a是除数,对应的余数b是0时,a就是最大公约数,在递推后得到后将其原样递归出来,即g传给g;而x=1,y=0,y-=a/b*x,x和y交换值,则是通过推导(gcd(a,b)=gcd(b,a%b),将x,y,a,b的关系表达出来,变换一下即可得到算法)得出的式子。
#include<iostream> using namespace std; typedef long long ll; void f(ll a,ll b,ll& d,ll& x,ll& y) { if(!b){d=a;x=1;y=0;} else{f(b,a%b,d,y,x);y-=a/b*x;} } int main() { int t; cin>>t; for(int i=0;i<t;i++) { ll x,k,p,q,g; cin>>x>>k; if(x%k==0)cout<<0<<" "<<k<<endl; else{f(x/k,x/k+1,g,p,q);cout<<p*x<<" "<<q*x<<endl;} } }