• 洛谷 P1292 倒酒


    题目描述

    Winy是一家酒吧的老板,他的酒吧提供两种体积的啤酒,a ml和b ml,分别使用容积为a ml和b ml的酒杯来装载。

    酒吧的生意并不好。Winy发现酒鬼们都非常穷。有时,他们会因为负担不起aml或者bml啤酒的消费,而不得不离去。因此,Winy决定出售第三种体积的啤酒(较小体积的啤酒)。

    Winy只有两种杯子,容积分别为a ml和b ml,而且啤酒杯是没有刻度的。他只能通过两种杯子和酒桶间的互相倾倒来得到新的体积的酒。

    为了简化倒酒的步骤,Winy规定:

    (1)a≥b;

    (2)酒桶容积无限大,酒桶中酒的体积也是无限大(但远小于桶的容积);

    (3)只包含三种可能的倒酒操作:

    ①将酒桶中的酒倒入容积为b ml的酒杯中;

    ②将容积为a ml的酒杯中的酒倒入酒桶;

    ③将容积为b ml的酒杯中的酒倒入容积为a ml的酒杯中。

    (4)每次倒酒必须把杯子倒满或把被倾倒的杯子倒空。

    Winy希望通过若干次倾倒得到容积为a ml酒杯中剩下的酒的体积尽可能小,他请求你帮助他设计倾倒的方案

    输入输出格式

    输入格式:

     

    两个整数a和b(0<b≤a≤10^9)

     

    输出格式:

     

    第一行一个整数c,表示可以得到的酒的最小体积。

    第二行两个整数Pa和Pb(中间用一个空格分隔),分别表示从体积为a ml的酒杯中倒出酒的次数和将酒倒入体积为b ml的酒杯中的次数。

    若有多种可能的Pa、Pb满足要求,那么请输出Pa最小的一个。若在Pa最小的情况下,有多个Pb满足要求,请输出Pb最小的一个。

     

    输入输出样例

    输入样例#1:
    5 3
    
    输出样例#1:
    1
    1 2
    

    说明

    样例解释:倾倒的方案为:

    1、桶->B杯;2、B杯->A杯;

    3、桶->B杯;4、B杯->A杯;

    5、A杯->桶; 6、B杯->A杯;

    题解: 扩展欧几里得

    a中酒全部到点就相当于对a取模了..然后假设倒入b中y次,则。

    by≡?(mod a),要求的就是最小的?,显然?就是gcd(a,b)。因为

    ax+by=?,?最小就是gcd(a,b)喽。然后扩展欧几里得就好了...

    一开始50,在最小解上花费了很长时间..

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    
    int a,b,x,y,r;
    
    int exgcd(int a,int b,int &x,int &y){
        if(b==0){
            x=1;y=0;
            return a;
        }
        int t,r=exgcd(b,a%b,x,y);
        t=x;x=y;y=t-a/b*y;
        return r;
    }
    
    int main(){
        scanf("%d%d",&a,&b);
        r=exgcd(a,b,x,y);
        x*=-1;a*=-1;
        while(x<0||y<0){
            x+=b/r;y-=a/r*(x>=0);
        }
        printf("%d
    ",r);
        printf("%d %d",x,y);
        return 0;
    }
  • 相关阅读:
    mongodb基础系列——数据库查询数据返回前台JSP(一)
    整型数组处理算法(十二)请实现一个函数:最长顺子。[风林火山]
    学习C++服务端一:MySql与C++
    【算法】深度优先搜索(DFS)III
    DOS cmd
    C# wpf程序获取当前程序版本
    Climbing Stairs
    Java深入
    非对称算法,散列(Hash)以及证书的那些事
    省市区镇(能够选四级)联动点击自己主动展开下一级
  • 原文地址:https://www.cnblogs.com/zzyh/p/7670141.html
Copyright © 2020-2023  润新知