题目连接:http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=21php
如下图片参考此微博,谢谢:https://blog.csdn.net/guozlh/article/details/50572347ios
三个水杯相互倒水的过程以下:spa
对于每一次倒水都会引发三个水杯水量状态的改变,这样就能够获得以下的一个解空间树:
.net
DFS-AC代码以下:code
#include
#include
#include
#include
#include
#include
#include
#define INF 1e8
using namespace std;
int v1,v2,v3,e1,e2,e3,vis[105][105],m;//标记某个肯定的序列,而且记录他的步数。。。真的应该用bfs写,干吗折腾本身
void dfs(int a, int b, int c,int count)
{
if(a == e1 && b == e2)
{
if(count < m)
{
m = count;
}
}
//dfs访问的是全解,第一次访问到的并非最短的。
if(!vis[a][b] || vis[a][b] > count)//若是第一次访问该序列的步数大于第二次访问该序列的步数
{
vis[a][b] = count;//则选择第二次的步数
//模拟倒水的过程
if(a != 0)
{
if(b != v2)
dfs(a>(v2-b) ? a-(v2-b):0, a>(v2-b) ? v2:a+b, c, count+1);
if(c != v3)
dfs(a>(v3-c) ? a-(v3-c):0, b, a>(v3-c) ? v3:a+c, count+1);
}
if(b != 0)
{
if(a != v1)
dfs(b>(v1-a) ? v1:a+b, b>(v1-a) ? b-(v1-a):0, c, count+1);
if(c != v3)
dfs(a, b>(v3-c) ? v3:b+c, b>(v3-c) ? b-(v3-c):0, count+1);
}
if(c != 0)
{
if(a != v1)
dfs(c>(v1-a) ? v1:a+c, b, c>(v1-a) ? c-(v1-a):0, count+1);
if(b != v2)
dfs(a, c>(v2-b) ? v2:b+c, b>(v2-b) ? c-(v2-b):0, count+1);
}
}
}
//搜索:在不少数据中不断地重复一个类似的动做寻找正确答案,首先要抽象地全面的扩充数据。
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
m = INF;
memset(vis,0,sizeof(vis));
scanf("%d%d%d",&v1,&v2,&v3);
scanf("%d%d%d",&e1,&e2,&e3);
dfs(v1,0,0,0);
if(m == INF)
printf("-1\n");
else
printf("%d\n",m);
}
return 0;
}
BFS-AC代码以下:blog
#include
#include
#include
#include
#include
#include
#include
using namespace std;
struct Node{
int a,b,c,step;
};
int v1,v2,v3,e1,e2,e3,vis[105][105];
int bfs(int a,int b,int c)
{
Node p;
p.a = a;
p.b = b;
p.c = c;
p.step = 0;
queue q;
q.push(p);
int count = 0;
while(!q.empty())
{
Node temp = q.front();
q.pop();
if(temp.a == e1 && temp.b == e2)
{
count = temp.step;
break;
}
int x = min(v2 - temp.b,temp.a);
if(x >= 0)
{
Node y;
y.a = temp.a-x;
y.b = temp.b+x;
y.c = temp.c;
y.step = temp.step+1;
if(!vis[y.a][y.b] && y.a >= 0 && y.b >= 0 && y.c >= 0)//在减的过程当中,可能出现小于零的状况
{
vis[temp.a][temp.b] = 1;
q.push(y);
}
}
x = min(v3 - temp.c,temp.a);
if(x >= 0)
{
Node y;
y.a = temp.a-x;
y.b = temp.b;
y.c = temp.c+x;
y.step = temp.step+1;
if(!vis[y.a][y.b] && y.a >= 0 && y.b >= 0 && y.c >= 0)
{
vis[temp.a][temp.b] = 1;
q.push(y);
}
}
x = min(v1 - temp.a,temp.b);
if(x >= 0)
{
Node y;
y.a = temp.a+x;
y.b = temp.b-x;
y.c = temp.c;
y.step = temp.step+1;
if(!vis[y.a][y.b] && y.a >= 0 && y.b >= 0 && y.c >= 0)
{
vis[temp.a][temp.b] = 1;
q.push(y);
}
}
x = min(v3 - temp.c,temp.b);
if(x >= 0)
{
Node y;
y.a = temp.a;
y.b = temp.b-x;
y.c = temp.c+x;
y.step = temp.step+1;
if(!vis[y.a][y.b] && y.a >= 0 && y.b >= 0 && y.c >= 0)
{
vis[temp.a][temp.b] = 1;
q.push(y);
}
}
x = min(v1 - temp.a,temp.c);
if(x >= 0)
{
Node y;
y.a = temp.a+x;
y.b = temp.b;
y.c = temp.c-x;
y.step = temp.step+1;
if(!vis[y.a][y.b] && y.a >= 0 && y.b >= 0 && y.c >= 0)
{
vis[temp.a][temp.b] = 1;
q.push(y);
}
}
x = min(v2 - temp.b,temp.c);
if(x >= 0)
{
Node y;
y.a = temp.a;
y.b = temp.b+x;
y.c = temp.c-x;
y.step = temp.step+1;
if(!vis[y.a][y.b] && y.a >= 0 && y.b >= 0 && y.c >= 0)
{
vis[temp.a][temp.b] = 1;
q.push(y);
}
}
}
if(count == 0 && (a != e1 || b != e2 || c != e3))
return -1;
else
return count;
}
int main()
{
int n;
scanf("%d",&n);
while(n--)
{
scanf("%d%d%d",&v1,&v2,&v3);
scanf("%d%d%d",&e1,&e2,&e3);
memset(vis,0,sizeof(vis));
int ans = bfs(v1,0,0);
printf("%d\n",ans);
}
return 0;
}