您的位置:首页 > 编程语言 > C语言/C++

【poj 3414】Pots 题意&题解&代码(C++)

2016-03-22 22:15 609 查看
题目链接:

http://poj.org/problem?id=3414

题意:

给出了两个瓶子的容量A,B, 以及一个目标水量C,

对A、B可以有如下操作:

FILL(i) 填满 i 壶

DROP(i) 倒空 i 壶

POUR(i,j) 把 i 壶的水倒入 j 壶

问经过哪几个操作后能使得任意一个瓶子的残余水量为C。

若不可能得到则输出impossible

题解:

原本一道bfs经典题就硬生生的被改成了恶心吃屎题,记录路径这种东西,唉。。。定pre数组,pre[i]表示标号i的状态由标号 pre[i] 转移而来,最后回溯着输出。

代码:

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
using namespace std;
int a,b,c;
struct node{
int x;int y;
}q[10005];
int ans,anss,h,t,vis[105][105],pre[10005],step[10005];
void dfs(int id)
{
if(step[id])
{
dfs(pre[id]);
if(step[id]==1 || step[id]==2)printf("FILL(%d)\n",step[id]);
if(step[id]==3 || step[id]==4)printf("DROP(%d)\n",step[id]-2);
if(step[id]==5)printf("POUR(1,2)\n");
if(step[id]==6)printf("POUR(2,1)\n");
}
}
int main()
{
memset(vis,0,sizeof(vis));
scanf("%d%d%d",&a,&b,&c);
ans=-1;
h++;t++;
q[h].x=0;
q[h].y=0;
vis[0][0]=1;
while(h<=t)
{
int nox=q[h].x;
int noy=q[h].y;
//      cout<<h<<endl;
if (nox==c || noy==c)
{
ans=h;
anss=vis[nox][noy]-1;
break;
}
if (nox<a && !vis[a][noy])
{
vis[a][noy]=vis[nox][noy]+1,t++,pre[t]=h,step[t]=1;
q[t].x=a,q[t].y=noy;
}
if (noy<b && !vis[nox][b])
{
vis[nox][b]=vis[nox][noy]+1,t++,pre[t]=h,step[t]=2;
q[t].x=nox,q[t].y=b;
}
if (nox!=0 && !vis[0][noy])
{
vis[0][noy]=vis[nox][noy]+1,t++,pre[t]=h,step[t]=3;
q[t].x=0,q[t].y=noy;
}
if (noy!=0 && !vis[nox][0])
{
vis[nox][0]=vis[nox][noy]+1,t++,pre[t]=h,step[t]=4;
q[t].x=nox,q[t].y=0;
}
int tmpx=max(nox+noy-b,0);
int tmpy=min(nox+noy,b);
if (!vis[tmpx][tmpy])
{
vis[tmpx][tmpy]=vis[nox][noy]+1,t++,pre[t]=h,step[t]=5;
q[t].x=tmpx,q[t].y=tmpy;
}
tmpx=min(nox+noy,a);
tmpy=max(nox+noy-a,0);
if (!vis[tmpx][tmpy])
{
vis[tmpx][tmpy]=vis[nox][noy]+1,t++,pre[t]=h,step[t]=6;
q[t].x=tmpx,q[t].y=tmpy;
}
h++;
}
if (ans==-1) printf("impossible\n");
else
{
printf("%d\n",anss);
dfs(ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: