HDU - 1495 非常可乐 (bfs)

题意:还是倒水问题:给出三个瓶子容积为 A,B,C :A =B+C;然后问倒几次才能够使其中两个瓶子中水相同且平分已有的水。一开始A瓶被装满水

思路:像装水这种操作的问题就是模拟,而dfs能够解决最少操作问题(通过记录操作数)

 

完整代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
int s[3] , vis[105][105][105];
 
struct cup{
  int v[3] , step;
}now;
 
int bfs(){
  queue<cup> q ;
  now.v[0] = s[0] ,now.v[1] = now.v[2] = now.step = 0;
  vis[now.v[0]][now.v[1]][now.v[2]] = 1;
  q.push(now);
  while(!q.empty()){
    now = q.front();
    if((now.v[0] == now.v[1] && now.v[2] == 0) || (now.v[0] == now.v[2] && now.v[1] == 0) || (now.v[1] == now.v[2] && now.v[0] == 0))
    //判断终止条件,即有一个杯子是空,另外两个杯子一样多
    {
      return now.step;
    }
    q.pop();
    for(int i = 0 ; i < 3 ; i ++){
      //模拟倒水的 6 种情况 a 倒 b,c  ||  b倒 a , c   || c 倒 a , b
        for(int j = 0 ; j < 3 ; j ++){
        if(i != j){ // 非自己倒给自己的过程,即其他的倒水过程
          int k = s[j] - now.v[j];
          if(k > now.v[i]){
            k = now.v[i];
          }
          cup next = now;
          //第 i 杯往第 j 杯里倒水过程
          next.v[i] = now.v[i] - k;
          next.v[j] = now.v[j] + k;
          next.step = now.step + 1;
          if(vis[next.v[0]][next.v[1]][next.v[2]] == 0){
            vis[next.v[0]][next.v[1]][next.v[2]] = 1;
            q.push(next);
          }
        }
      }
    }
  }
  return -1;
}
 
int main(){
  while(cin >> s[0] >> s[1] >> s[2] ){
      if(!(s[0] + s[1] + s[2])) break;  
    memset(vis,0,sizeof(vis));
    if(s[0] != s[1] + s[2]){
      printf("NO\n");
      break;
    }
    else{
      int ans = bfs();
      if(ans == -1)
        printf("NO\n");
      else
        printf("%d\n",ans);
    }
  }
  return 0 ;
}

 

posted @ 2019-07-29 13:09  Tianwell  阅读(119)  评论(0)    收藏  举报