Pots

题目大意:有2个杯子(刚开始的时候是空的),容量为a,b。求通过以下三种操作判断能否使得出现为c升的水,如果可以的话,求最短的步骤数

1、drop  给1或者2倒光水

2、fill        给1或者2倒满水

3、pour 1 to 2  或者 pour 2 to 1  

每次操作只能对一个杯子进行操作

思路:bfs,至于保存路径的话,也容易实现,因为对于每一个状态,其路径都是不同的,所以大可以把路径作为状态的一个属性。

 

AC Program:

#include<iostream>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
#include<iomanip>
#include<string>
#include<stdio.h>
#include<queue>
using namespace std;
int u,v,w;
int flag[103][103];
//每瓶水最多容量为100,利用此数组来标记访问过的状态 
struct node
{
  int a,b;
  string r;     
}tmp,ans;
void bfs()
{
   queue<node>que;
   memset(flag,0,sizeof(flag));
   ans.a=0,ans.b=0,ans.r="";
   //把每个状态的路径作为此状态的一个属性 
   que.push(ans);
   flag[0][0]=1;
   while(!que.empty())
   {     
      tmp=que.front();
      que.pop();
      if(tmp.a==w || tmp.b==w)//找到目标,准备输出 
      {
//通过BFS的往外扩展出来的路径一定是最短的 
         //output!!!
         string kg=tmp.r;
         int len=kg.length();
         cout<<len<<endl; 
         for(int i=0;i<len;i++)
         {
            switch(kg[i])
            {
               case '0': cout<<"DROP(1)"<<endl;break;
               case '1': cout<<"DROP(2)"<<endl;break;
               case '2': cout<<"FILL(1)"<<endl;break;
               case '3': cout<<"FILL(2)"<<endl;break;
               case '4': cout<<"POUR(1,2)"<<endl;break;
               case '5': cout<<"POUR(2,1)"<<endl;break;             
            }        
         }
         return;            
      }
      for(int i=0;i<6;i++)//进行搜索 
      { 
//利用swith是更简便的输出字符串 
//6个入口,操作6次 
          switch(i)
          {
             case 0:{//操作:倒掉1
                       ans.a=0,ans.b=tmp.b,ans.r=tmp.r+"0";
                       if(!flag[ans.a][ans.b])
                         {
                            flag[ans.a][ans.b]=1;//标记 
                            que.push(ans);                    
                         }
                       break;//注意了啦不要漏了 
                    }
             case 1:{//操作:倒掉2
                       ans.a=tmp.a,ans.b=0,ans.r=tmp.r+"1";
                       if(!flag[ans.a][ans.b])
                         {
                            flag[ans.a][ans.b]=1;
                            que.push(ans);                    
                         }
                       break;
                    }
             case 2:{//操作:倒满1
                       ans.a=u, ans.b=tmp.b, ans.r=tmp.r+"2";
                       if(!flag[ans.a][ans.b])
                         {
                            flag[ans.a][ans.b]=1;
                            que.push(ans);                    
                         }
                       break;
                    }
             case 3:{//操作:倒满2
                       ans.a=tmp.a, ans.b=v, ans.r=tmp.r+"3";
                       if(!flag[ans.a][ans.b])
                         {
                            flag[ans.a][ans.b]=1;
                            que.push(ans);                    
                         }
                       break;
                    }
             case 4:{//操作:倒1给2 
                       if(tmp.a>v-tmp.b)//注意是ans还是tmp 
                           {
                             ans.a=tmp.a-(v-tmp.b) , ans.b=v, ans.r=tmp.r+"4";
                             if(!flag[ans.a][ans.b])
                              {
                                 flag[ans.a][ans.b]=1;
                                 que.push(ans);                    
                              }               
                           }
                       else
                           {
                              ans.a=0 , ans.b=tmp.a+tmp.b, ans.r=tmp.r+"4";                
                              if(!flag[ans.a][ans.b])
                              {
                                 flag[ans.a][ans.b]=1;
                                 que.push(ans);                    
                              }               
                           }
                       
                       break;
                       
                    }
             case 5:{//操作:倒2给1 
                       if(u-tmp.a<tmp.b)
                       {
                          ans.a=u,ans.b=tmp.b-(u-tmp.a),ans.r=tmp.r+"5";
                          if(!flag[ans.a][ans.b])
                         {
                            flag[ans.a][ans.b]=1;
                            que.push(ans);                    
                         }                
                       }
                       else
                       {
                         ans.a=tmp.a+tmp.b,ans.b=0,ans.r=tmp.r+"5"; 
                         if(!flag[ans.a][ans.b])
                         {
                            flag[ans.a][ans.b]=1;
                            que.push(ans);                    
                         } 
                       }
                       
                       break;
                       
                    }         
          }      
      }                
   }
   cout<<"impossible"<<endl;  
}
int main()
{
cin>>u>>v>>w;
bfs();
//system("pause");
return 0;} 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值