NOIP2016模拟赛Jams 倒酒(pour) - 扩展欧几里得
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NOIP2016模拟赛Jams 倒酒(pour) - 扩展欧几里得相关的知识,希望对你有一定的参考价值。
Problem Pour
题目大意
一个人要用两个装水量一定的杯子互相倒水,求最后能搞出来最少的水量是多少以及倒的次数。
Solution
我们不知道为什么突然就发现了这个最少的水量一定就是最大公约数。
然后我们不知道为什么突然就想到了扩展欧几里得算法。
首先我们有$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$
AC Code
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) - 扩展欧几里得的主要内容,如果未能解决你的问题,请参考以下文章