Pots

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

题意:给你两个罐子的体积,然后让你只用这两个罐子量出给定k体积的水。
题解:这里可以把两个罐子看成是一个二维的图,然后体积的水就是图中其中一个坐标是k的点。可以直接BFS,每次操作就相当于从当前的点向外扩展,并且记录当前的路径,即可。
其中可以用1,2,3,4,5,6六个数字来分别对应六种操作,然后用一个int类型的数组记录路径就可以。

#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cstdio>
#include<queue>
using namespace std;
struct Node{
  int counts1;//第一个pot中当前的水
  int counts2;//第二个pot中当前的水
  int step;//当前的步数
  int path[102];//记录到达这一步之前的以及这一步的路径
};
int counts[102][102];//counts【i】【j】表示到达第一个pot中是i,
int a,b,k;          //第二个pot中是j这种状态所需要的最小的步数
void print(int x){//打印出对印标记的输出路径上每一个数字代表一种操作,六个数字对印六种操作
  if(x==1)printf("FILL(1)\n");
  if(x==2)printf("FILL(2)\n");
  if(x==3)printf("DROP(1)\n");
  if(x==4)printf("DROP(2)\n");
  if(x==5)printf("POUR(2,1)\n");
  if(x==6)printf("POUR(1,2)\n");
}
void  BFS(){
    bool flag=false;//标记是否有解
   for(int i=0;i<=100;i++)
    for(int j=0;j<=100;j++)//初始化
      counts[i][j]=10000000;
     queue<Node>Q;
     Node tt;//队首元素
     tt.counts1=0;//初始时候都是0,0
     tt.counts2=0;
     tt.step=0;
     counts[0][0]=0;//别忘了注意这里的初始化0
     Q.push(tt);
     while(!Q.empty()){
        Node temp=Q.front();//取出队首元素
        Q.pop();
        int  step=temp.step;
        int  sum1=temp.counts1;
        int  sum2=temp.counts2;
        if(sum1==k){//只要其中一个罐子出现k,则直接输出
                printf("%d\n",step);
               for(int i=1;i<=step;i++)//输出路径
                 print(temp.path[i]);
                 flag=true;
                  break;
             }
        if(sum2==k){
              printf("%d\n",step);
               for(int i=1;i<=step;i++)
                print(temp.path[i]);
                flag=true;
                 break;
            }
        if(sum1<a&&counts[a][sum2]>step+1){//当第一个罐子没满,这是可以把第一个罐子灌满
            Node ttt;
            ttt.counts1=a;
            ttt.counts2=sum2;
            ttt.step=step+1;
            for(int i=1;i<=step;i++)//复制之前的路径
                ttt.path[i]=temp.path[i];
            ttt.path[step+1]=1;
            Q.push(ttt);
            counts[a][sum2]=step+1;

        }
         if(sum2<b&&counts[sum1][b]>step+1){//灌满第二个罐子
            Node ttt;
            ttt.counts1=sum1;
            ttt.counts2=b;
            ttt.step=step+1;
             for(int i=1;i<=step;i++)
                ttt.path[i]=temp.path[i];
            ttt.path[step+1]=2;
            Q.push(ttt);
            counts[sum1][b]=step+1;
        }
      if(sum1>0&&counts[0][sum2]>step+1){//清空第一个罐子
            Node ttt;
            ttt.counts1=0;
            ttt.counts2=sum2;
            ttt.step=step+1;
             for(int i=1;i<=step;i++)
                ttt.path[i]=temp.path[i];
            ttt.path[step+1]=3;
            Q.push(ttt);
            counts[0][sum2]=step+1;
        }
         if(sum2>0&&counts[sum1][0]>step+1){//清空第二个罐子
            Node ttt;
            ttt.counts1=sum1;
            ttt.counts2=0;
            ttt.step=step+1;
             for(int i=1;i<=step;i++)
                ttt.path[i]=temp.path[i];
            ttt.path[step+1]=4;
            Q.push(ttt);
            counts[sum1][0]=step+1;
        }
          if(sum2+sum1>=a&&counts[a][sum2+sum1-a]>step+1){//把第二个导入第一个并且第一个装满之后,第二个还有剩余
            Node ttt;
            ttt.counts1=a;
            ttt.counts2=sum2+sum1-a;
            ttt.step=step+1;
             for(int i=1;i<=step;i++)
                ttt.path[i]=temp.path[i];
            ttt.path[step+1]=5;
            Q.push(ttt);
            counts[a][sum2+sum1-a]=step+1;
        }
         if(sum2+sum1<a&&counts[sum1+sum2][0]>step+1){////把第二个导入第一个并且第一个装满之后,第二个没有剩余
            Node ttt;
            ttt.counts1=sum1+sum2;
            ttt.counts2=0;
            ttt.step=step+1;
             for(int i=1;i<=step;i++)
                ttt.path[i]=temp.path[i];
            ttt.path[step+1]=5;
            Q.push(ttt);
            counts[sum1+sum2][0]=step+1;
        }
         if(sum2+sum1>=b&&counts[sum1+sum2-b][b]>step+1){//与上面正好相反
            Node ttt;
            ttt.counts1=sum1+sum2-b;
            ttt.counts2=b;
            ttt.step=step+1;
             for(int i=1;i<=step;i++)
                ttt.path[i]=temp.path[i];
            ttt.path[step+1]=6;
            Q.push(ttt);
            counts[sum1+sum2-b][b]=step+1;
        }
         if(sum2+sum1<b&&counts[0][sum1+sum2]>step+1){
            Node ttt;
            ttt.counts1=0;
            ttt.counts2=sum1+sum2;
            ttt.step=step+1;
             for(int i=1;i<=step;i++)
                ttt.path[i]=temp.path[i];
            ttt.path[step+1]=6;
            Q.push(ttt);
            counts[0][sum1+sum2]=step+1;
        }

     }
     if(!flag)printf("impossible\n");
}
int main(){
    scanf("%d%d%d",&a,&b,&k);
    BFS();
}
View Code

 

posted on 2014-01-25 23:04  天依蓝  阅读(271)  评论(0编辑  收藏  举报

导航