题意:
给你两个容器,分别能装下A升水和B升水,并且可以进行以下操作
FILL(i) 将第i个容器从水龙头里装满(1 ≤ i ≤ 2);
DROP(i) 将第i个容器抽干
POUR(i,j) 将第i个容器里的水倒入第j个容器(这次操作结束后产生两种结果,一是第j个容器倒满并且第i个容器依旧有剩余,二是第i个容器里的水全部倒入j中,第i个容器为空)
现在要求你写一个程序,来找出能使其中任何一个容器里的水恰好有C升,找出最少操作数并给出操作过程
思路:
BFS。
我的代码不知道为什么WA,实在找不出错,,只能先学习一下巨巨的写法……
我的:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const int maxn=200005;
const double eps=1e-8;
const double PI = acos(-1.0);
struct node
{
int a,b,step,mode,id,fro;
};
int a,b,c,vis[110][110];
void bfs()
{
memset(vis,0,sizeof(vis));
node all[10005],st;
stack <int> ans;
queue<node> q;
st.a=0,st.b=0,st.step=0,st.mode=0,st.id=0,st.fro=-1;
int cnt=0;
q.push(st);
all[0]=st;
vis[st.a][st.b]=1;
while(!q.empty())
{
node t=q.front();
q.pop();
for(int i=1; i<=6; i++)
{
node s;
switch(i)
{
case 1:
s.a=a;
s.mode=1;
s.b=t.b;
break;
case 2:
s.b=b;
s.a=t.a;
s.mode=2;
break;
case 3:
s.a=0;
s.b=t.b;
s.mode=3;
break;
case 4:
s.b=0;
s.a=t.a;
s.mode=4;
case 5:
if(t.a<=b-t.b)
{
s.a=0;
s.b=t.b+t.a;
s.mode=5;
}
else
{
s.a=t.a-(b-t.b);
s.b=b;
s.mode=5;
}
break;
case 6:
if(t.b<=a-t.a)
{
s.b=0;
s.a=t.a+t.b;
s.mode=6;
}
else
{
s.b=t.b-(a-t.a);
s.a=a;
s.mode=6;
}
break;
}
if(!vis[s.a][s.b])
{
++cnt;
s.step=t.step+1;
s.fro=t.id;
s.id=cnt;
all[cnt]=s;
if(s.a==c||s.b==c)
{
cout<<s.step<<endl;
while(s.fro>=0)
{
// cout<<t.mode<<endl;
ans.push(s.mode);
s= all[s.fro];
}
while(!ans.empty())
{
int tmp=ans.top();
ans.pop();
switch(tmp)
{
case 1:
cout<<"FILL(1)"<<endl;
break;
case 2:
cout<<"FILL(2)"<<endl;
break;
case 3:
cout<<"DROP(1)"<<endl;
break;
case 4:
cout<<"DROP(2)"<<endl;
break;
case 5:
cout<<"POUR(1,2)"<<endl;
break;
case 6:
cout<<"POUR(2,1)"<<endl;
break;
}
}
return ;
}
q.push(s);
vis[s.a][s.b]=1;
}
}
}
cout<<"impossible"<<endl;
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
cin>>a>>b>>c;
bfs();
return 0;
}
AC代码:
#include <iostream>
#include <algorithm>
using namespace std;
#include <cstring>
#include <queue>
#include <stack>
struct cup
{
int x, y;
int step;
int flag;//标记操作
cup *pre;//记录路径
};
queue<cup>Q;
stack<int>R;
int a, b, e;
int vis[117][117]={0};//标记当前状态是否到达过
int ans;
void BFS(int x, int y)
{
cup c;
cup t[317];//目前瓶子里剩余的水量
c.x = 0, c.y = 0;
c.flag = 0;
c.pre = NULL;
c.step = 0;
Q.push(c);
vis[x][y] = 1;
int count = -1;
while(!Q.empty())
{
count++;
t[count] = Q.front();
Q.pop();
for(int i = 1; i <= 6; i++)
{
switch(i)
{
case 1: //fill a
c.x = a;
c.y = t[count].y;
c.flag = 1;
break;
case 2: //fill b
c.x = t[count].x;
c.y = b;
c.flag = 2;
break;
case 3: //drop a
c.x = 0;
c.y = t[count].y;
c.flag = 3;
break;
case 4: //drop b
c.x = t[count].x;
c.y = 0;
c.flag = 4;
break;
case 5: //pour a to b
if(t[count].x > b-t[count].y)
{
c.x = t[count].x-(b-t[count].y);
c.y = b;
}
else
{
c.x = 0;
c.y = t[count].y+t[count].x;
}
c.flag = 5;
break;
case 6: //pour b to a
if(t[count].y > a-t[count].x)
{
c.y = t[count].y - (a-t[count].x);
c.x = a;
}
else
{
c.x = t[count].x+t[count].y;
c.y = 0;
}
c.flag = 6;
break;
}
if(vis[c.x][c.y])
continue;
vis[c.x][c.y] = 1;
c.step = t[count].step+1;
c.pre = &t[count];
if(c.x == e || c.y == e)
{
ans = c.step;
while(c.pre)
{
R.push(c.flag);
c = *c.pre;
}
return;
}
Q.push(c);
}
}
}
void print()
{
while(!R.empty())
{
int i = R.top();
R.pop();
switch(i)
{
case 1:cout<<"FILL(1)"<<endl;break;
case 2:cout<<"FILL(2)"<<endl;break;
case 3:cout<<"DROP(1)"<<endl;break;
case 4:cout<<"DROP(2)"<<endl;break;
case 5:cout<<"POUR(1,2)"<<endl;break;
case 6:cout<<"POUR(2,1)"<<endl;break;
}
}
}
int main()
{
cin >>a>>b>>e;
BFS(0,0);
if(ans == 0)
cout<<"impossible"<<endl;
else
{
cout<<ans<<endl;
print();
}
return 0;
}