码迷,mamicode.com
首页 > 其他好文 > 详细

【NOIP2016模拟赛(五)】Jams 倒酒(pour) - 扩展欧几里得

时间:2017-09-17 17:39:57      阅读:147      评论:0      收藏:0      [点我收藏+]

标签:用两个   noip   约数   扩展欧几里得算法   没有   get   print   col   lin   

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) - 扩展欧几里得

标签:用两个   noip   约数   扩展欧几里得算法   没有   get   print   col   lin   

原文地址:http://www.cnblogs.com/skylynf/p/7536145.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!