NYOJ-三个水杯-DFS and BFS解法

题目链接:http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=21

以下图片参考此微博,谢谢:https://blog.csdn.net/guozlh/article/details/50572347

三个水杯相互倒水的过程如下:


对于每一次倒水都会引起三个水杯水量状态的改变,这样就可以得到如下的一个解空间树:


DFS-AC代码如下:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<vector>
#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代码如下:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<vector>

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<Node> 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;
}

猜你喜欢

转载自blog.csdn.net/cutedumpling/article/details/79998701