题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=21
题目思路 : 广搜
题目ac代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iterator>
#include <string>
#include <stack>
#include <queue>
using namespace std;
const int M = 100;
bool vis[M][M][M]; //记录是否出现过此状态
struct Cup
{
int v[3]; //用数组记录三个杯子中的状态很方便编码
int step; // 最小步数
}s,e; // 杯子大小,最终状态
bool del(Cup &now, int start, int end ) // 传的是引用,start杯子向end杯子倒水
{
int sum = now.v[start] + now.v[end] ;
if(now.v[start] != 0 && now.v[end] != s.v[end]) // 能倒水
{
now.v[end] = (now.v[start] >= (s.v[end] - now.v[end])) ? s.v[end] : now.v[end] + now.v[start];
now.v[start] = sum - now.v[end] ;
if(vis[now.v[0]][now.v[1]][now.v[2]] == false) //没有出现过这个状态就返回true入队列
{
vis[now.v[0]][now.v[1]][now.v[2]] = true;
return true;
}
}
return false;
}
int bfs()
{
queue<Cup>q;
struct Cup tmp = {s.v[0], 0, 0};
tmp.step = 0;
q.push(tmp);
vis[s.v[0]][0][0] = true;
while(!q.empty())
{
Cup tmp = q.front(),now;
q.pop();
now = tmp;
if(now.v[0] == e.v[0] && now.v[1] == e.v[1] && now.v[2] == e.v[2])
return now.step ;
for(int i = 0; i < 3; i++) //遍历倒水的六个状态
{
for(int j = 0; j < 3; j++)
{
now = tmp;
if( i != j && del(now,i,j))
{
now.step = tmp.step + 1;
q.push(now);
}
}
}
}
return -1;
;
}
int main()
{
int T;
cin >> T;
while(T --)
{
memset(vis, false, sizeof(vis));
cin >> s.v[0] >> s.v[1] >> s.v[2];
cin >> e.v[0] >> e.v[1] >> e.v[2];
cout << bfs() << endl;
}
return 0;
}