题意:给你两个罐子,你可以执行以下操作:
1. FILL(i) 将罐子 i 装满水
2. DROP(i) 将罐子 i 中的水倒掉
3. POUR(i,j) 将罐子 i 中的水倒入罐子 j 中,若 i 中的容量大于 j 中的容量, 那么 i 中有剩余。
现在给出A,B两个罐子的容量,开始时A,B皆空,问能不能经过一系列操作使得A,B中有一个装有C水?
题解:
#include <queue>
#include <iostream>
using namespace std;
int a,b,c;
int vis[101][101], father[10001];
char path[10][10] = { "", "FILL(1)", "FILL(2)", "DROP(1)", "DROP(2)", "POUR(1,2)", "POUR(2,1)"};
struct State
{
int pot1, pot2, step, oper; /* pot1 表示1中的水量, pot2 表示2中的水量, step记录到达当前状态所经历的步骤,oper为操作类型 */
} state[10001];
void print( int x ) /* 输出结果 */
{
if ( father[x] != 0 )
print(father[x]);
printf("%s\n", path[state[x].oper]);
}
int bfs()
{
queue<int> Q;
state[0].pot1 = 0;
state[0].pot2 = 0;
state[0].oper = state[0].step = father[0] = 0;
vis[0][0] = 1;
Q.push ( 0 );
int cnt = 0, cur, temp;
while ( ! Q.empty () )
{
cur = Q.front ();
Q.pop ();
if ( state[cur].pot1 == c || state[cur].pot2 == c ) /* 任意一个的容量为C则返回最后一个状态的编号 */
return cur;
if ( ! vis[a][state[cur].pot2] ) /* 将 1 装满 */
{
cnt++;
father[cnt] = cur;
state[cnt].oper = 1;
state[cnt].pot1 = a;
state[cnt].pot2 = state[cur].pot2;
state[cnt].step = state[cur].step + 1;
vis[state[cnt].pot1][state[cnt].pot2] = 1;
Q.push(cnt);
}
if ( ! vis[state[cur].pot1][b] ) /* 将2装满 */
{
cnt++;
father[cnt] = cur;
state[cnt].oper = 2;
state[cnt].pot1 = state[cur].pot1;
state[cnt].pot2 = b;
state[cnt].step = state[cur].step + 1;
vis[state[cnt].pot1][state[cnt].pot2] = 1;
Q.push(cnt);
}
if ( ! vis[0][state[cur].pot2] ) /* 将1清空 */
{
cnt++;
father[cnt] = cur;
state[cnt].oper = 3;
state[cnt].pot1 = 0;
state[cnt].pot2 = state[cur].pot2;
state[cnt].step = state[cur].step + 1;
vis[state[cnt].pot1][state[cnt].pot2] = 1;
Q.push(cnt);
}
if ( ! vis[state[cur].pot1][0] ) /* 将2清空 */
{
cnt++;
father[cnt] = cur;
state[cnt].oper = 4;
state[cnt].pot1 = state[cur].pot1;
state[cnt].pot2 = 0;
state[cnt].step = state[cur].step + 1;
vis[state[cnt].pot1][state[cnt].pot2] = 1;
Q.push(cnt);
}
temp = state[cur].pot1 > b-state[cur].pot2 ? b-state[cur].pot2 : state[cur].pot1;
if ( ! vis[state[cur].pot1-temp][state[cur].pot2+temp] ) /* 将 1 倒入 2 */
{
cnt++;
father[cnt] = cur;
state[cnt].oper = 5;
state[cnt].pot1 = state[cur].pot1 - temp;
state[cnt].pot2 = state[cur].pot2 + temp;
state[cnt].step = state[cur].step + 1;
vis[state[cnt].pot1][state[cnt].pot2] = 1;
Q.push(cnt);
}
temp = state[cur].pot2 > a-state[cur].pot1 ? a-state[cur].pot1 : state[cur].pot2;
if ( ! vis[state[cur].pot1+temp][state[cur].pot2-temp] ) /* 将2倒入1 */
{
cnt++;
father[cnt] = cur;
state[cnt].oper = 6;
state[cnt].pot1 = state[cur].pot1+temp;
state[cnt].pot2 = state[cur].pot2-temp;
state[cnt].step = state[cur].step + 1;
vis[state[cnt].pot1][state[cnt].pot2] = 1;
Q.push(cnt);
}
}
return -1;
}
int main()
{
scanf("%d%d%d",&a,&b,&c);
memset(vis,0,sizeof(vis));
memset(state,0,sizeof(state));
int temp = bfs();
if ( temp == -1 )
printf("impossible\n");
else if ( temp == 0 )
printf("%d\n",temp);
else
{
printf("%d\n",state[temp].step);
print(temp);
}
return 0;
}