• 宽搜--分红酒


    宽搜--分红酒

    题目描述:有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

     


    code

     #include<set>
     #include<queue>
     #include<cstdio>
     #include<sstream>
     #include<cstring>
     #include<iostream>
     #include<algorithm>
     using namespace std;
     
     int column[4]={9,7,4,2};//该数组为各个杯子的最大容量
     int endst[4];
     set<string>vis;
     struct node{
      int st[4];
      int step;
     };
     
     
     queue<node>q;
     
     string i2s(int i){
      string s;
      stringstream ss;
      ss<<i;
      ss>>s;
      return s;
     }
     
     void bfs(){
      while(!q.empty()){
      node h = q.front();
      q.pop();
     
      if(h.st[0]==endst[0] && h.st[1]==endst[1] && h.st[2] == endst[2] && h.st[3] == endst[3]){
      cout<<h.step<<endl;
      return;
      }
     
      for(int i=0;i<4;i++){
      for(int j=0;j<4;j++){
      //把第i个杯子的酒倒入第j个瓶子中
      if(i==j)continue;
      if(h.st[i]==0)continue;
      if(h.st[j]==column[j])continue;
      if(h.st[i] + h.st[j] <= column[j]){
      //此时会把i酒杯倒空
      node tmp = h;
      tmp.step = h.step + 1;
      tmp.st[i] = 0;
      tmp.st[j] = h.st[i] + h.st[j];
      string s = "";
      for(int i=0;i<4;i++){
      s += i2s(tmp.st[i]);
      }
      vis.insert(s);
      q.push(tmp);
      }else{
      //此时会把j酒杯倒满
      node tmp = h;
      tmp.step = h.step + 1;
      tmp.st[j] = column[j];
      tmp.st[i] = h.st[i] - (column[j] - h.st[j]);
      string s = "";
      for(int i=0;i<4;i++){
      s += i2s(tmp.st[i]);
      }
      vis.insert(s);
      q.push(tmp);
     


     

    }  
    int main(){ 
    int sum = 0; 
    for(int i=0;i<4;i++){ 
    scanf("%d",&endst[i]); 
    sum += endst[i]; 

     
    //初始判断,  
    if(sum != 9 || endst[0] > column[0] || endst[1] > column[1] || endst[2] > column[2] || endst[3] > column[3]){ 
    cout<<"-1"<<endl; 
    return 0; 

    //首节点 
    node startst; 
    startst.st[0] = 9,startst.st[1] = 0,startst.st[2] = 0,startst.st[3] = 0,startst.step=0; 
    q.push(startst); 
    //初始状态标记 
    string s = ""; 
     
    for(int i=0;i<4;i++){ 
    s += i2s(startst.st[i]); 

     
    vis.insert(s); 
     
    bfs(); 
    return 0; 
    }

     

  • 相关阅读:
    PHP中simpleXML递归实现XML文件与数组的相互转化(原创)
    关于本地服务器localhost请求Forbidden解决办法
    PHP中XPATH 实现xml及html文件快速解析(附xml做小型数据库实现六级单词快速查询实例)
    win8忘记开机密码解决方法汇总
    HTML5的FileAPI实现文件的读取及超大文件的上传
    FormData实现form表单的数据打包
    Ajax_iframe文件上传
    深入浅出JSONP--解决ajax跨域问题
    2017ACM暑期多校联合训练
    2017ACM暑期多校联合训练
  • 原文地址:https://www.cnblogs.com/yuanshixiao/p/14611266.html
Copyright © 2020-2023  润新知