有装满水的6升的杯子、空的3升杯子和1升杯子, 3个杯子中都没有刻度. 在不使用其他道具的情况下, 是否可以量出4升的水呢?
你的任务是解决一般性的问题:设大、中、小3个杯子的容量分别为a,b,c,最初只有大杯子装满水,其他两个杯子为空。最少需要多少步才能让某一个杯子中的水有x升呢?你需要打印出每步操作后各个杯子中的水量(0<c<b<a<1000)。
样例输入 | 样例输出 |
2 6 3 1 4 9 6 3 1 | 最少需要3步:(6,0,0)–>(3,3,0)–>(3,2,1)–>(4,2,0) No |
话不多说,先上码:
// // main.cpp // // Created by Soildom on 2017/11/18. // Copyright © 2017年 Soildom. All rights reserved. // #include <iostream> #include <queue> using namespace std; const int MAXN=1000; class node { public: int cup[3]={0},last=0,depth=0; }; int vis[MAXN][MAXN],i_cup[3],target; node v[MAXN]; queue<int> number; void progress(int x) { if (!x) { printf("(%d,0,0)-->",i_cup[0]); return; } progress(v[x].last); printf("(%d,%d,%d)-->",v[x].cup[0],v[x].cup[1],v[x].cup[2]); } void bfs() { int k=0; while (!number.empty()) number.pop(); v[k].cup[0]=i_cup[0]; vis[v[k].cup[1]][v[k].cup[2]]=1; number.push(k); while (!number.empty()) { if ((v[number.front()].cup[0]==target)||(v[number.front()].cup[1]==target)||(v[number.front()].cup[2]==target)) { cout<<"最少需要"<<v[number.front()].depth<<"步:"; progress(v[number.front()].last); printf("(%d,%d,%d)",v[number.front()].cup[0],v[number.front()].cup[1],v[number.front()].cup[2]); cout<<endl; return; } for (int out=0; out<3; out++) { for (int in=0; in<3; in++) { if (in==out) continue; int num=min(v[number.front()].cup[out],i_cup[in]-v[number.front()].cup[in]); if (!num) continue; node tem=v[number.front()]; tem.cup[in]=v[number.front()].cup[in]+num; tem.cup[out]=v[number.front()].cup[out]-num; if (!vis[tem.cup[1]][tem.cup[2]]) { vis[tem.cup[1]][tem.cup[2]]=1; v[++k]=tem; v[k].last=number.front(); v[k].depth=v[number.front()].depth+1; number.push(k); } } } number.pop(); } cout<<"No"<<endl; } int main() { int T; cin>>T; while (T--) { memset(vis, 0, sizeof(vis)); cin>>i_cup[0]>>i_cup[1]>>i_cup[2]>>target; bfs(); } }