题目1457:非常可乐(广度优先遍历BFS)

本文提供了一种使用广度优先搜索解决“非常可乐”问题的方法。通过定义状态转移方程,实现容器间的液体倒转操作,寻找将初始状态转换为目标状态的最短步骤。适用于算法竞赛中的状态搜索问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:http://ac.jobdu.com/problem.php?pid=1457

详解链接:https://github.com/zpfbuaa/JobduInCPlusPlus

参考代码:

//
//  1457 非常可乐.cpp
//  Jobdu
//
//  Created by PengFei_Zheng on 22/04/2017.
//  Copyright © 2017 PengFei_Zheng. All rights reserved.
//
 
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <cmath>
#include <queue>
#define MAX_SIZE 101
using namespace std;
 
int s, n, m;
 
struct N{
    int a;
    int b;
    int c;
    int t;
};
 
queue<N> myQueue;
bool visit[MAX_SIZE][MAX_SIZE][MAX_SIZE];
 
void x2y(int &x,int size_x, int &y,int size_y){
    if(size_y - y >= x){
        y+=x;
        x = 0;
    }else{
        x -=(size_y-y);
        y = size_y;
    }
}
 
int BFS(int s, int n, int m){
    while(!myQueue.empty()){
        N nowP = myQueue.front();
        myQueue.pop();
        int a, b, c;
        a = nowP.a;
        b = nowP.b;
        c = nowP.c;
        x2y(a,s,b,n);// a--->b
        if(visit[a][b][c]==false){
            visit[a][b][c]=true;
            N tmp;
            tmp.a = a;
            tmp.b = b;
            tmp.c = c;
            tmp.t = nowP.t+1;
            if((a==s/2 && b==s/2) || (a==s/2 &&c==s/2) || (b==s/2 && c==s/2) ) return tmp.t;
            myQueue.push(tmp);
        }
        a = nowP.a;
        b = nowP.b;
        c = nowP.c;
        x2y(a,s,c,m);// a--->c
        if(visit[a][b][c]==false){
            visit[a][b][c]=true;
            N tmp;
            tmp.a = a;
            tmp.b = b;
            tmp.c = c;
            tmp.t = nowP.t+1;
            if((a==s/2 && b==s/2) || (a==s/2 &&c==s/2) || (b==s/2 && c==s/2) ) return tmp.t;
            myQueue.push(tmp);
        }
        a = nowP.a;
        b = nowP.b;
        c = nowP.c;
        x2y(b,n,a,s);// b--->a
        if(visit[a][b][c]==false){
            visit[a][b][c]=true;
            N tmp;
            tmp.a = a;
            tmp.b = b;
            tmp.c = c;
            tmp.t = nowP.t+1;
            if((a==s/2 && b==s/2) || (a==s/2 &&c==s/2) || (b==s/2 && c==s/2) ) return tmp.t;
            myQueue.push(tmp);
        }
        a = nowP.a;
        b = nowP.b;
        c = nowP.c;
        x2y(b,n,c,m);// b--->c
        if(visit[a][b][c]==false){
            visit[a][b][c]=true;
            N tmp;
            tmp.a = a;
            tmp.b = b;
            tmp.c = c;
            tmp.t = nowP.t+1;
            if((a==s/2 && b==s/2) || (a==s/2 &&c==s/2) || (b==s/2 && c==s/2) ) return tmp.t;
            myQueue.push(tmp);
        }
        a = nowP.a;
        b = nowP.b;
        c = nowP.c;
        x2y(c,m,a,s);// c--->a
        if(visit[a][b][c]==false){
            visit[a][b][c]=true;
            N tmp;
            tmp.a = a;
            tmp.b = b;
            tmp.c = c;
            tmp.t = nowP.t+1;
            if((a==s/2 && b==s/2) || (a==s/2 &&c==s/2) || (b==s/2 && c==s/2) ) return tmp.t;
            myQueue.push(tmp);
        }
        a = nowP.a;
        b = nowP.b;
        c = nowP.c;
        x2y(c,m,b,n);// c--->b
        if(visit[a][b][c]==false){
            visit[a][b][c]=true;
            N tmp;
            tmp.a = a;
            tmp.b = b;
            tmp.c = c;
            tmp.t = nowP.t+1;
            if((a==s/2 && b==s/2) || (a==s/2 &&c==s/2) || (b==s/2 && c==s/2) ) return tmp.t;
            myQueue.push(tmp);
        }
    }
    return -1;
}
 
int main(){
    while(scanf("%d%d%d",&s,&n,&m)!=EOF){
        if(s==0) break;
        if(s%2==1){
            printf("NO\n");
            continue;
        }
        for(int i = 0 ; i <= s ; i++){
            for(int j = 0 ; j <= n ; j++){
                for(int k = 0 ; k <= m ; k++){
                    visit[i][j][k]=false;
                }
            }
        }
        while(!myQueue.empty()) myQueue.pop();
         
        N tmp;
        tmp.a = s;
        tmp.b = tmp.c = tmp.t = 0;
        myQueue.push(tmp);
        visit[s][0][0]=true;
        int ans = BFS(s,n,m);
        ans == -1 ? printf("NO\n") : printf("%d\n",ans);
    }
}
/**************************************************************
    Problem: 1457
    User: zpfbuaa
    Language: C++
    Result: Accepted
    Time:10 ms
    Memory:2528 kb
****************************************************************/

 

转载于:https://www.cnblogs.com/zpfbuaa/p/6750319.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值