蓝桥杯预赛 分红酒问题 9 7 4 2

来源:互联网 发布:工业大数据发展战略 编辑:程序博客网 时间:2024/04/27 23:48

     真心有点佩服自己了,一个这么明显的BFS都A不出来,努力不够啊。

  题目:   

  有4个红酒瓶子,它们的容量分别是:9升, 7升, 4升, 2升
  开始的状态是 [9,0,0,0],也就是说:第一个瓶子满着,其它的都空着。
  允许把酒从一个瓶子倒入另一个瓶子,但只能把一个瓶子倒满或把一个瓶子倒空,不能有中间状态。这样的一次倒酒动作称为1次操作。
  假设瓶子的容量和初始状态不变,对于给定的目标状态,至少需要多少次操作才能实现?
  本题就是要求你编程实现最小操作次数的计算。
  输入:最终状态(逗号分隔)
  输出:最小操作次数(如无法实现,则输出-1)
例如:
输入:
9,0,0,0
应该输出:
0
输入:
6,0,0,3
应该输出:
-1
输入:
7,2,0,0
应该输出:
2

代码里面有解释,建议直接看代码。

其实这题很明显,BFS啊,唯一需要注意的就是状态的处理,不能盲目的搜。(我是用一个四维数组来存储状态的)

#include<cstdio>#include<cstring>#include<iostream>#include<queue>using namespace std;typedef struct{int bot[4];//瓶子的现状int cou;//求最小步}Node;int vis[10][8][5][3];int cap[4]={9,7,4,2};//瓶子的容量int app[4];//瓶子的末状int BFS(){  queue<Node> p;  Node now,next;  p.push((Node){{9,0,0,0},0});  vis[9][0][0][0]=false;  while(!p.empty())  {   now = p.front();   p.pop();   if(now.bot[0]==app[0]&&now.bot[1]==app[1]&&now.bot[2]==app[2]&&now.bot[3]==app[3])    return now.cou;   for(int i=0; i<4; ++i)//寻找倒的容器,所以不能为零。   {     if(now.bot[i]==0)        continue;    for(int e=0; e<4; ++e) //寻找装的容器    {     if(i==e||now.bot[e]==cap[e])        continue;     next.cou = now.cou+1;     for(int j=0; j<4; ++j)        next.bot[j]=now.bot[j];     if(now.bot[i]+now.bot[e]>=cap[e])     {        next.bot[e]=cap[e];        next.bot[i]=now.bot[i]+now.bot[e]-cap[e];     }     else     {       next.bot[i]=0;       next.bot[e]=now.bot[i]+now.bot[e];     }     if(vis[next.bot[0]][next.bot[1]][next.bot[2]][next.bot[3]])       {        vis[next.bot[0]][next.bot[1]][next.bot[2]][next.bot[3]]=false;        p.push(next);       }    }   }  }  return -1;}int main(){    char m[4];    while(cin>> app[0]>>m[1]>> app[1]>>m[2]>> app[2]>>m[3]>>app[3])    {     memset(vis,true,sizeof(vis));    int sum = 0;    for(int i=0; i<4; ++i)      sum += app[i];    if(sum != 9)    {      cout <<"-1"<<endl;      continue;    }    int g = BFS();    if(g<0)     cout <<"-1"<<endl;    else        cout<<g<<endl;    }    return 0;}