zoukankan      html  css  js  c++  java
  • NYOJ #21 三个水杯(bfs)

    描述

    给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子。三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算。现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数。

    输入

    第一行一个整数N(0<N<50)表示N组测试数据
    接下来每组测试数据有两行,第一行给出三个整数V1 V2 V3 (V1>V2>V3 V1<100 V3>0)表示三个水杯的体积。
    第二行给出三个整数E1 E2 E3 (体积小于等于相应水杯体积)表示我们需要的最终状态。

    输出

    每行输出相应测试数据最少的倒水次数。如果达不到目标状态输出-1。

    样例输入

    2
    6 3 1
    4 1 1
    9 3 2
    7 1 1

    样例输出

    3
    -1

    解题思路:bfs求最少的倒水次数,每次都有6种倒水可能,标记一下三个水杯的容量状态,用队列来模拟倒水过程,如果出现某个过程达到最终的倒水状态,则直接返回其倒水次数;否则直到队空,返回-1,说明不能到达最终的容量状态。详解看代码。

    AC代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int t,Vmax[3],Est[3],Cur[3];
     4 bool vis[105][105][105];
     5 struct node{int a,b,c,step;}cur,tmp;
     6 queue<node> que;
     7 int bfs(int x){
     8     while(!que.empty())que.pop();
     9     cur.a=x,cur.b=cur.c=cur.step=0;
    10     vis[cur.a][cur.b][cur.c]=true;
    11     que.push(cur);
    12     while(!que.empty()){
    13         cur=que.front();que.pop();
    14         if(cur.a==Est[0]&&cur.b==Est[1]&&cur.c==Est[2])return cur.step;//到达最终的状态
    15         for(int i=0;i<3;++i){
    16             for(int j=0;j<3;++j){//6种倒水可能
    17                 tmp=cur;Cur[0]=tmp.a,Cur[1]=tmp.b,Cur[2]=tmp.c;//每次重新赋值
    18                 if(i!=j&&Cur[i]>0&&Cur[j]<Vmax[j]){//i-->j,如果第i个桶的水量大于0,并且第j个桶的水量不超过其最大容量
    19                     int gg=min(Cur[i],Vmax[j]-Cur[j]);//如果第j个桶剩余容量小于第i个桶里的水量,那么只能倒Vmax[j]-Cur[j];反之,将第i个桶的水量全部倒给第j个桶
    20                     Cur[i]-=gg,Cur[j]+=gg;// i--->j
    21                     if(!vis[Cur[0]][Cur[1]][Cur[2]]){//状态未出现过
    22                         vis[Cur[0]][Cur[1]][Cur[2]]=true;
    23                         tmp.a=Cur[0],tmp.b=Cur[1],tmp.c=Cur[2];//重新赋值
    24                         tmp.step++;
    25                         que.push(tmp);
    26                     }
    27                 }
    28             }
    29         }
    30     }
    31     return -1;//不满足条件则返回-1
    32 }
    33 int main(){
    34     while(cin>>t){
    35         while(t--){
    36             for(int i=0;i<3;++i)cin>>Vmax[i];
    37             for(int i=0;i<3;++i)cin>>Est[i];
    38             memset(vis,false,sizeof(vis));
    39             cout<<bfs(Vmax[0])<<endl;
    40         }
    41     }
    42     return 0;
    43 }
  • 相关阅读:
    10.1~10.15学习情况
    ACM-ICPC 2018 沈阳赛区网络预赛
    打卡4
    打卡3
    tab 简单的tab
    css 圆形动画
    pdf和图片之间的转换
    对list进行分组
    C# 打开所在文件夹
    读取xml文件
  • 原文地址:https://www.cnblogs.com/acgoto/p/9813792.html
Copyright © 2011-2022 走看看