武汉企业最好用的手机优化软件
【题目描述】
有三个容器,容量分别为 a,b,c(a> b > c ),一开始a装满油,现在问是否只靠abc三个容器量出k升油。如果能就输出“yes”,并且说明最少倒几次,否则输出“no”。例如:10升油在10升的容器中,另有两个7升和3升的空容器,要求用这三个容器倒油,使得最后在abc三个容器中有一个刚好存有5升油,问最少的倒油次数是多少?(每次倒油,A容器倒到B容器,或者A内的油倒完,或者B容器倒满。
10 7 3
(10 0 0)
(3 7 0):第一次
(3 4 3):第二次
(6 4 0):第三次
(6 1 3):第四次
(9 1 0):第五次
(9 0 1):第六次
(2 7 1):第七次
(2 5 3):第八次,出现5了。
Input
【输入格式】
有多组测试数据。
输入a,b,c, k四个正整数( 100 ≥ a > b > c≥1 , 1≤k< 100 )
Output
【输出格式】
如果能得到k就输出两行。
第一行“yes”,第二行为最少的次数
否则输出“no”
Sample Input
10 7 3 5
Sample Output
yes 8
分析:这道题的做法和这节的问题A下面提示的有一些区别,这道题能做的操作只有把油从容器X倒到容器Y中,不可以从外面补充,也不可以把油直接倒掉。因此总共只有6种可能的操作:把油从a倒进b;把油从a倒进c;把油从b倒进c;把油从b倒进a;把油从c倒进b;把油从c倒进a.
搞清楚这点之后,用BFS就可以做了。
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>
#include <cstdio>
#include <queue>
#include <stack>
#include <ctime>
#include <cmath>
#include <map>
#include <set>
#include<unordered_map>
#define INF 0x3f3f3f3f
#define db1(x) cout<<#x<<"="<<(x)<<endl
#define db2(x,y) cout<<#x<<"="<<(x)<<", "<<#y<<"="<<(y)<<endl
#define db3(x,y,z) cout<<#x<<"="<<(x)<<", "<<#y<<"="<<(y)<<", "<<#z<<"="<<(z)<<endl
#define db4(x,y,z,a) cout<<#x<<"="<<(x)<<", "<<#y<<"="<<(y)<<", "<<#z<<"="<<(z)<<", "<<#a<<"="<<(a)<<endl
#define db5(x,y,z,a,r) cout<<#x<<"="<<(x)<<", "<<#y<<"="<<(y)<<", "<<#z<<"="<<(z)<<", "<<#a<<"="<<(a)<<", "<<#r<<"="<<(r)<<endl
using namespace std;typedef struct node
{int cap_a,cap_b,cap_c,cnt_a,cnt_b,cnt_c,index;
}node;node pour_a2b(node now,int a,int b)
{node temp=now;if(a==1&&b==2){if(temp.cnt_a<temp.cap_b-temp.cnt_b)temp.cnt_b+=temp.cnt_a,temp.cnt_a=0;else temp.cnt_a-=temp.cap_b-temp.cnt_b,temp.cnt_b=temp.cap_b;}else if(a==2&&b==3){if(temp.cnt_b<temp.cap_c-temp.cnt_c)temp.cnt_c+=temp.cnt_b,temp.cnt_b=0;else temp.cnt_b-=temp.cap_c-temp.cnt_c,temp.cnt_c=temp.cap_c;}else if(a==1&&b==3){if(temp.cnt_a<temp.cap_c-temp.cnt_c)temp.cnt_c+=temp.cnt_a,temp.cnt_a=0;else temp.cnt_a-=temp.cap_c-temp.cnt_c,temp.cnt_c=temp.cap_c;}temp.index=now.index+1;return temp;
}node pour_b2a(node now,int a,int b)
{node temp=now;if(a==2&&b==1){if(temp.cnt_b<temp.cap_a-temp.cnt_a)temp.cnt_a+=temp.cnt_b,temp.cnt_b=0;else temp.cnt_b-=temp.cap_a-temp.cnt_a,temp.cnt_a=temp.cap_a;}else if(a==3&&b==2){if(temp.cnt_c<temp.cap_b-temp.cnt_b)temp.cnt_b+=temp.cnt_c,temp.cnt_c=0;else temp.cnt_c-=temp.cap_b-temp.cnt_b,temp.cnt_b=temp.cap_b;}else if(a==3&&b==1){if(temp.cnt_c<temp.cap_a-temp.cnt_a)temp.cnt_a+=temp.cnt_c,temp.cnt_c=0;else temp.cnt_c-=temp.cap_a-temp.cnt_a,temp.cnt_a=temp.cap_a;}temp.index=now.index+1;return temp;
}int main(void)
{#ifdef testfreopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);clock_t start=clock();#endif //testnode beg;int tar;while(~scanf("%d%d%d%d",&beg.cap_a,&beg.cap_b,&beg.cap_c,&tar)){int f=0;bool flag[101][101][101];memset(flag,0,sizeof(flag));if(max(beg.cap_a,max(beg.cap_b,beg.cap_c))<tar)printf("no\n");else{beg.cnt_a=beg.cap_a;beg.index=0;queue<node>que;que.push(beg);flag[beg.cnt_a][beg.cnt_b][beg.cnt_c]=1;while(!que.empty()){node fir=que.front(),temp=fir;que.pop();if(temp.cnt_a==tar||temp.cnt_b==tar||temp.cnt_c==tar){f=1;printf("yes\n%d\n",temp.index);break;}for(int i=1;i<=3;++i){if(i<=2){temp=pour_a2b(fir,i,i+1);if(flag[temp.cnt_a][temp.cnt_b][temp.cnt_c]==0)flag[temp.cnt_a][temp.cnt_b][temp.cnt_c]=1,que.push(temp);temp=pour_b2a(fir,i+1,i);if(flag[temp.cnt_a][temp.cnt_b][temp.cnt_c]==0)flag[temp.cnt_a][temp.cnt_b][temp.cnt_c]=1,que.push(temp);}else{temp=pour_a2b(fir,1,3);if(flag[temp.cnt_a][temp.cnt_b][temp.cnt_c]==0)flag[temp.cnt_a][temp.cnt_b][temp.cnt_c]=1,que.push(temp);temp=pour_b2a(fir,3,1);if(flag[temp.cnt_a][temp.cnt_b][temp.cnt_c]==0)flag[temp.cnt_a][temp.cnt_b][temp.cnt_c]=1,que.push(temp);}}}if(!f)printf("no\n");}}#ifdef testclockid_t end=clock();double endtime=(double)(end-start)/CLOCKS_PER_SEC;printf("\n\n\n\n\n");cout<<"Total time:"<<endtime<<"s"<<endl; //s为单位cout<<"Total time:"<<endtime*1000<<"ms"<<endl; //ms为单位#endif //testreturn 0;
}