POJ-3414-Pots

POJ-3414-Pots

传送门

这道题是一道判断很多的bfs~

题目大意:就是我们小时候玩的两个杯子相互倒水问题,然后最终达到一个预期值。现在分别给你容器为A,B的两个杯子,有一下几个步骤可以实行,问某个杯子是否能达到所给定的预期值C,不能则输出"impossible",否则输出相应的步骤。初始的时候两个杯子都没有水,是空的。
操作如下:
1.FILL(i) //从水龙头装满某个杯子
2.DROP(i) //把i杯子里面的水倒到排水管里面
3.POUR(i, j) //将i水杯里面的水倒在j水杯里(此方案下必有一个杯子为空)

本题思路:
这道题就是步骤比较多的BFS,最后还要输出步骤,这里我们用递归可以实现。
bfs里面我们分别进行:FILL(1), FILL(2), DROP(1), DROP(2), POUR(1, 2), POUR(2, 1)即可。
同时我们在这个过程中还需要保存路径,具体方法就是记录前一个步骤。然后用递归输出即可。
递归出口我们就可以设置成:初始化开始操作的前一个步骤为-1, -1;
这道题,我TLE。。原因竟然是使用"."成员运算符过多。。
后来我全改了一遍然后ac了。。。惊!!

代码部分:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define mst(a, n) memset(a, n, sizeof(a))
using namespace std;
const int N = 1e2 + 15;

struct node
{
	int x, y;
	int prex, prey;
	int step;
};
struct Map
{
	int prex, prey;
	int step;
	string s;
}ma[N][N];

int vis[N][N];
int a, b, c;

void print(int x, int y)
{
	if (ma[x][y].prex == -1 && ma[x][y].prey == -1)
	{
		return ;
	}
	print(ma[x][y].prex, ma[x][y].prey);
	cout << ma[x][y].s << endl;
}

void bfs()
{
	node next, now;
	string t;
	mst(vis, 0);
	queue<node> q;
	now.x = 0, now.y = 0, now.step = 0, now.prex = -1, now.prey = -1;
	q.push(now);
	vis[0][0] = 1;
	ma[0][0].prex = ma[0][0].prey = -1;
	ma[0][0].step = 0;
	
	while (!q.empty())
	{
		now = q.front();
		q.pop();
		if (now.x == c || now.y == c)
		{
			cout << now.step << endl;
			print(now.x, now.y);
			return ;
		}
		//fill 1
		if (now.x < a && (!vis[a][now.y] || ma[a][now.y].step > now.step + 1))
		{
			vis[a][now.y] = 1;
			next = now;
			next.x = a;
			next.step++;
			next.prex = now.x;
			next.prey = now.y;
			q.push(next);
			t = "FILL(1)";
			ma[a][next.y].s = t;
			ma[a][next.y].step = now.step + 1;
			ma[a][next.y].prex = now.x;
			ma[a][next.y].prey = now.y;
		}
		//fill 2
		if (now.y < b && (!vis[now.x][b] || ma[now.x][b].step > now.step + 1))
		{
			vis[now.x][b] = 1;
			next = now;
			next.y = b;
			next.step = now.step + 1;
			next.prex = now.x;
			next.prey = now.y;
			q.push(next);
			t = "FILL(2)";
			ma[next.x][b].s = t;
			ma[next.x][b].step = now.step + 1;
			ma[next.x][b].prex = now.x;
			ma[next.x][b].prey = now.y;
		}
		//drop1
		if (now.x && (!vis[0][now.y] || ma[0][now.y].step > now.step + 1))
		{
			vis[0][now.y] = 1;
			next = now;
			next.x = 0;
			next.step = now.step + 1;
			next.prex = now.x;
			next.prey = now.y;
			q.push(next);
			t = "DROP(1)";
			ma[0][next.y].s = t;
			ma[0][next.y].step = now.step + 1;
			ma[0][next.y].prex = now.x;
			ma[0][next.y].prey = now.y;
		}
		//drop2
		if (now.y && (!vis[now.x][0] || ma[now.x][0].step > now.step + 1))
		{
			vis[now.x][0] = 1;
			next = now;
			next.y = 0;
			next.step = now.step + 1;
			next.prex = now.x;
			next.prey = now.y;
			q.push(next);
			t = "DROP(2)";
			ma[next.x][0].s = t;
			ma[next.x][0].step = now.step + 1;
			ma[next.x][0].prex = now.x;
			ma[next.x][0].prey = now.y;
		}
		//pour 1 to 2
		if (now.x)
		{
			int aa, bb;
			int need = b - now.y;
			if (need >= now.x)
			{
				aa = 0;
				bb = now.y + now.x;
			}
			else
			{
				aa = now.x - need;
				bb = b;
			}
			if (!vis[aa][bb] || ma[aa][bb].step > now.step + 1)
			{
				vis[aa][bb] = 1;
				next.x = aa;
				next.y = bb;
				next.step = now.step + 1;
				next.prex = now.x;
				next.prey = now.y;
				q.push(next);
				t = "POUR(1,2)";
				ma[aa][bb].s = t;
				ma[aa][bb].step = now.step + 1;
				ma[aa][bb].prex = now.x;
				ma[aa][bb].prey = now.y; 
			}
		}
		//pour 2 to 1
		if (now.y)
		{
			int aa, bb;
			int need = a - now.x;
			if (need >= now.y)
			{
				bb = 0;
				aa = now.x + now.y;
			}
			else
			{
				bb = now.y - need;
				aa = a;
			}
			if (!vis[aa][bb] || ma[aa][bb].step > now.step + 1)
			{
				vis[aa][bb] = 1;
				next.x = aa;
				next.y = bb;
				next.step = now.step + 1;
				next.prex = now.x;
				next.prey = now.y;
				q.push(next);
				t = "POUR(2,1)";
				ma[aa][bb].s = t;
				ma[aa][bb].step = now.step + 1;
				ma[aa][bb].prex = now.x;
				ma[aa][bb].prey = now.y; 
			}
		}
	}
	cout << "impossible\n";
}

int main()
{
	cin >> a >> b >> c;
	bfs();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

娃娃酱斯密酱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值