标签:用两个 noip 约数 扩展欧几里得算法 没有 get print col lin
一个人要用两个装水量一定的杯子互相倒水,求最后能搞出来最少的水量是多少以及倒的次数。
我们不知道为什么突然就发现了这个最少的水量一定就是最大公约数。
然后我们不知道为什么突然就想到了扩展欧几里得算法。
首先我们有$ax + by =\gcd(a,b)$
然后我们就可以想到,这个x和y其实就是倒的次数嘛。
于是就用扩欧算出来了x,y。但是还没有完,题目要求我们求出最小的b。
那么我们知道,只要我们找到一组特殊的解 x0 和 y0,我们就可以用 x0 和 y0 表示出通解。
只要乱搞这个操作,直到搞到最小的y就可以了。
$x = x0 + (b/\gcd)*t$
$y = y0 – (a/\gcd)*t$
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 int x,y,a,b,ans; 5 int ex(int a,int b,int &x,int &y){ 6 if(b==0)return x=1,y=0,a; 7 int ret=ex(b,a%b,x,y); 8 int tmp=x;x=y,y=tmp-a/b*x; 9 return ret; 10 } 11 int main(){ 12 scanf("%d%d",&a,&b); 13 int ans=ex(a,b,x,y); 14 x=-x;a=-a; 15 for(;x<0||y<0;x+=b/ans*(x<0),y-=a/ans*(x>=0)); 16 printf("%d\n%d %d",ans,x,y); 17 }
【NOIP2016模拟赛(五)】Jams 倒酒(pour) - 扩展欧几里得
标签:用两个 noip 约数 扩展欧几里得算法 没有 get print col lin
原文地址:http://www.cnblogs.com/skylynf/p/7536145.html