倒酒

时间:2019-09-08
本文章向大家介绍倒酒,主要包括倒酒使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题目描述

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杯;

分析:

本题是扩欧的扩展题目,但是核心思想还是扩欧,而本题最大问题在于我们事实上只做了一遍扩欧,求出来的不一定是最小值,所以还需调整。

CODE:

 1 #include <iostream>  
 2 #include <cstdio> 
 3 #include <cmath>
 4 using namespace std;
 5 const int M=10005;
 6 int a,b,now;
 7 int s[M],t[M],q[M];
 8 int main(){
 9     cin>>a>>b;
10     int bb=b,aa=a;
11     //if (a>b) swap(a,b);
12     s[0]=t[1]=1;
13     s[1]=t[0]=0;
14     now=1;
15     while (b){
16         q[now]=a/b;
17         swap(a,b);
18         b%=a;
19         now++;
20         s[now]=s[now-2]-q[now-1]*s[now-1];
21         t[now]=t[now-2]-q[now-1]*t[now-1];
22     }
23     int ans=s[now-1]*aa+t[now-1]*bb;
24     while (s[now-1]>0) s[now-1]-=aa;
25     while (1) {
26         if (s[now-1]+aa>0) break;
27         s[now-1]+=aa;
28     }
29     cout<<ans<<endl;
30     t[now-1]=(ans-s[now-1]*aa)/(bb*ans);
31     cout<<abs(s[now-1])<<" "<<t[now-1]<<endl;
32     //system("pause");
33     return 0;
34 }

原文地址:https://www.cnblogs.com/kanchuang/p/11131744.html