nyoj 21 三个水杯

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

思路:问最少的次数,肯定广搜

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
struct node{
    int v[3];//水杯的容量
    int state[3];//当前水杯里水的状态
    int stemp;
}st,en,u,e;
int book[105][105][105];//用来标记
void BFS(){
     int i,j,num,f=0;
     queue<node>q;
     while(!q.empty()) q.pop();
     for(i=0;i<3;i++)
        u.v[i]=st.v[i];

     u.state[0]=u.v[0];
     u.state[1]=u.state[2]=0;//开始的状态
     u.stemp=0;
     book[u.state[0]][u.state[1]][u.state[2]]=1;
     q.push(u);
    // printf("R nstate[0]=%d state[1]=%d state[2]=%d\n",u.state[0],u.state[1],u.state[2]);
     while(!q.empty()){
        u=q.front();
        q.pop();
        //printf("C nstate[0]=%d state[1]=%d state[2]=%d\n",u.state[0],u.state[1],u.state[2]);
        if(u.state[0]==en.state[0] && u.state[1]==en.state[1]  && u.state[2]==en.state[2]){//判断是否达到所需状态
            f=1;
            printf("%d\n",u.stemp);
            break;
        }

        for(i=0;i<3;i++){
            for(j=0;j<3;j++){
                e=u;//e是每一种倒水方式
                if(i!=j){
                   num=u.v[j]-u.state[j];//记录的是j水杯所需要的水量
                   if(u.state[i]<num)//i往j里倒水,判断此时i里有没有足够的水
                       num=u.state[i];
                  e.state[j]+=num;
                   e.state[i]-=num;//倒水的过程
                   if(book[e.state[0]][e.state[1]][e.state[2]]==0){
                       book[e.state[0]][e.state[1]][e.state[2]]=1;
                       e.stemp=u.stemp+1;
                       q.push(e);
                      // printf("R state[0]=%d state[1]=%d state[2]=%d\n",e.state[0],e.state[1],e.state[2]);
                   }
                }

            }
        }

     }
     if(f==0)
        printf("-1\n");

}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        memset(book,0,sizeof(book));
        scanf("%d%d%d",&st.v[0],&st.v[1],&st.v[2]);
        scanf("%d%d%d",&en.state[0],&en.state[1],&en.state[2]);
        BFS();
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值