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