HDU 1495 BFS

看了题解才明白要用BFS...接下来要弄清BFS DFS的异同

代码有点太长了...感觉还能优化...先把题补完了再回来想吧

#include 
#include
#include 
#include 
#include
using namespace std;
const int maxn = 120;
int s, n, m;
int visit[maxn][maxn];
//改进...其实二维就可以记录三维的状态 因为s=n+m
struct node
{
	int s, n, m, step;
};
bool check(int x, int y, int z)
{
	if (x == 0 && y == z) return true;
	if (y == 0 && x == z) return true;
	if (z == 0 && x == y)  return true;
	return false;
}
int BFS(void)
{
	queue q;
	node a, temp;
	a.s = s, a.n = 0, a.m = 0, a.step = 0;//初始状态
	visit[a.s][a.n] = 0;
	q.push(a);
	while (!q.empty())
	{
		a = q.front();
		q.pop();//出队
		if (check(a.s, a.n, a.m))
			return a.step;
						  //然后是六个方向广搜 n->s n->m  s->n s->m m->s m->n
		if (a.n)//如果n瓶中还有 n->s ,n->m
		{
			if (a.n > s - a.s)//n瓶能将s瓶倒满
			{
				temp = a;
				temp.n = temp.n - (s - temp.s);//转移过程
				temp.s = s;//装满了
				if (!visit[temp.s][temp.n])//如果之前没访问过这个状态 入队
				{
					temp.step = a.step + 1;
					q.push(temp);
					visit[temp.s][temp.n] = 1;
				}
			}
			else//n瓶不能将s瓶倒满
			{
				temp = a;
				temp.s = temp.n + temp.s;
				temp.n = 0;
				if (!visit[temp.s][temp.n])//如果之前没访问过这个状态 入队
				{
					temp.step = a.step + 1;
					q.push(temp);
					visit[temp.s][temp.n] = 1;
				}
			}

			if (a.n > m - a.m)//n瓶能将m瓶倒满
			{
				temp = a;
				temp.n = temp.n - (m - temp.m);//转移过程
				temp.m = m;//装满了
				if (!visit[temp.s][temp.n])//如果之前没访问过这个状态 入队
				{
					temp.step = a.step + 1;
					q.push(temp);
					visit[temp.s][temp.n] = 1;
				}
			}
			else//n瓶不能将m瓶倒满
			{
				temp = a;
				temp.m += temp.n;
				temp.n = 0;
				if (!visit[temp.s][temp.n])//如果之前没访问过这个状态 入队
				{
					temp.step = a.step + 1;
					q.push(temp);
					visit[temp.s][temp.n] = 1;
				}
			}
		}
		if (a.m)//仿照上面的
		{
			if (a.m > s - a.s)
			{
				temp = a;
				temp.m = temp.m - (s - temp.s);
				temp.s = s;//装满了
				if (!visit[temp.s][temp.n])//如果之前没访问过这个状态 入队
				{
					temp.step = a.step + 1;
					q.push(temp);
					visit[temp.s][temp.n] = 1;
				}
			}
			else
			{
				temp = a;
				temp.s += temp.m;
				temp.m = 0;
				if (!visit[temp.s][temp.n])
				{
					temp.step = a.step + 1;
					q.push(temp);
					visit[temp.s][temp.n] = 1;
				}
			}
			if (a.m > n - a.n)
			{
				temp = a;
				temp.m = temp.m - (n - temp.n);
				temp.n = n;//装满了
				if (!visit[temp.s][temp.n])
				{
					temp.step = a.step + 1;
					q.push(temp);
					visit[temp.s][temp.n] = 1;
				}
			}
			else
			{
				temp = a;
				temp.n = temp.n + temp.m;
				temp.m = 0;
				if (!visit[temp.s][temp.n])//如果之前没访问过这个状态 入队
				{
					temp.step = a.step + 1;
					q.push(temp);
					visit[temp.s][temp.n] = 1;
				}
			}

		}
		if (a.s)//同上
		{
			if (a.s > n - a.n)
			{
				temp = a;
				temp.s = temp.s - (n - temp.n);
				temp.n = n;//装满了
				if (!visit[temp.s][temp.n])//如果之前没访问过这个状态 入队
				{
					temp.step = a.step + 1;
					q.push(temp);
					visit[temp.s][temp.n] = 1;
				}
			}
			else
			{
				temp = a;
				temp.n = temp.n + temp.s;/////////////
				temp.s = 0;
				if (!visit[temp.s][temp.n])
				{
					temp.step = a.step + 1;
					q.push(temp);
					visit[temp.s][temp.n] = 1;
				}
			}
			if (a.s > m - a.m)
			{
				temp = a;
				temp.s = temp.s - (m - temp.m);
				temp.m = m;//装满了
				if (!visit[temp.s][temp.n])
				{
					temp.step = a.step + 1;
					q.push(temp);
					visit[temp.s][temp.n] = 1;
				}
			}
			else
			{
				temp = a;
				temp.m = temp.s + temp.m;
				temp.s = 0;
				if (!visit[temp.s][temp.n])//如果之前没访问过这个状态 入队
				{
					temp.step = a.step + 1;
					q.push(temp);
					visit[temp.s][temp.n] = 1;
				}
			}
		}
	}
	return 0;//如果队列空了 说明不能完成任务
}

int main()
{
	while (scanf("%d%d%d", &s, &n, &m))
	//while(cin>>s>>n>>m)
	{
		if (s == 0 && n == 0 && m == 0) break;
		if (s % 2 == 1)
		{
			printf("NO\n");
			//cout << "NO\n";
			continue;
		}
		memset(visit, 0, sizeof(visit));
		int ans = BFS();
		if (ans) printf("%d\n", ans);
			//cout << ans << endl;
		else printf("NO\n");
			//cout << "NO" << endl;
	}
}
//一开始RE 检查了一下并没有数组越界的等问题 其实是程序的小细节错了...由此可见样例是真的水...
//BFS DFS还是要多做点题 熟悉一下模板

你可能感兴趣的:(算法学习,搜索)