POJ 3414 Pots

bfs优先队列,把操作名称存入对应的下标,分六种情况讨论入队。
#include <iostream>
#include <stdio.h>
#include <queue>
#include <vector>
using namespace std;
const int N = 110;
int vis[N][N];
int point[N*N];
char option[][10] = {"#","FILL(1)","FILL(2)", "DROP(1)","DROP(2)","POUR(1,2)","POUR(2,1)"}; //操作
struct node
{
int k1,k2; //k1:第一杯水 k2:第二杯水
int opnum; //当前操作
int nownum,prenum; //当前下标,前驱
int step; //操作步数
bool operator < (const node &c) const //步数小的优先出队
{
return step > c.step;
}
};
priority_queue<node> q;
vector<node> v;
void print(int num) //打印路径
{
int idx = 1;
while(v[num].nownum) //存储下标
{
point[idx++] = v[num].nownum;
num = v[num].prenum;
}
int i = idx-1;
while(i) //输出
{
puts(option[v[point[i]].opnum]);
i--;
}
}
void bfs(int x,int y, int ans)
{
bool flag = true;
node now;
now.k1 = now.k2 = now.nownum = now.prenum = now.step = 0;
q.push(now);
vis[0][0] = 1;
v.push_back(now);
int idx = 0;
while(!q.empty())
{
now = q.top();
q.pop();
if(now.k1 == ans || now.k2 == ans) //满足条件
{
flag =false;
printf("%d\n",now.step); //输出步数
print(now.nownum); //打印路径
break;
}
node Next;
for(int i = 1; i <= 6; i++)
{
if(i == 1) //装满第一杯水
{
Next.k1 = x;
Next.k2 = now.k2;
}
if(i == 2) //装满第二杯水
{
Next.k1 = now.k1;
Next.k2 = y;
}
if(i == 3) //放干第一杯水
{
Next.k1 = 0;
Next.k2 = now.k2;
}
if(i == 4) //放干第二杯水
{
Next.k1 = now.k1;
Next.k2 = 0;
}
if(i == 5) //第一杯水倒入第二杯水中
{
if(now.k1 + now.k2 <= y) //不能装满或刚好装满第二杯水
{
Next.k1 = 0;
Next.k2 = now.k1+now.k2;
}
else //能够装满且还有剩余
{
Next.k1 = now.k1 + now.k2 - y;
Next.k2 = y;
}
}
if(i == 6) //第二杯水倒入一杯水中
{
if(now.k1+now.k2 <= x) //不能或刚好装满
{
Next.k1 = now.k1 + now.k2;
Next.k2 = 0;
}
else //装满
{
Next.k1 = x;
Next.k2 = now.k1 + now.k2 - x;
}
}
Next.opnum = i; //记录当前操作下标
if(!vis[Next.k1][Next.k2])
{
idx++; //操作次数,当前的操作下标
Next.nownum = idx;
vis[Next.k1][Next.k2] = 1;
Next.step = now.step + 1;
Next.prenum = now.nownum;
v.push_back(Next);
q.push(Next);
}
}
}
if(flag) puts("impossible");
}
int main()
{
int A,B,C;
scanf("%d %d %d",&A,&B,&C);
bfs(A,B,C);
return 0;
}
永远年轻 永远热泪盈眶!

浙公网安备 33010602011771号