UVA10603Fill题解--BFS

Posted rye-catcher

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA10603Fill题解--BFS相关的知识,希望对你有一定的参考价值。

题目链接

https://cn.vjudge.net/problem/UVA-10603

分析

经典的倒水问题,直接BFS.

对于喜闻乐见的状态判重,一开始想来个哈希函数把一个三元组映射成一个数,后面发现数据很小直接三维数组,后面又发现总水量是固定值,直接二维(bool)数组就好了

然后每次取出状态更新下答案,搜索时就是枚举将哪个杯子的水倒入哪个杯子还是很好写的,记得要状态还原

忽然发现最近只会写写水题过活了

代码

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cctype>
#include <queue>
#define ll long long 
#define ri register int 
#define ull unsigned long long 
using std::priority_queue;
using std::min;
using std::swap;
template <class T>inline void read(T &x){
    x=0;int ne=0;char c;
    while(!isdigit(c=getchar()))ne=c==‘-‘;
    x=c-48;
    while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
    x=ne?-x:x;return ;
}
const int maxn=205;
const int inf=0x7fffffff;
int ans=inf,step=0;
int a,b,c,d;
struct Sta{
    int bot[3];
    int sum;
    Sta(){bot[0]=bot[1]=bot[2]=sum=0;}
    Sta(int _x,int _y,int _z,int _sum){bot[0]=_x,bot[1]=_y,bot[2]=_z,sum=_sum;}
    inline bool update(){
        for(ri i=0;i<3;i++){
            if(bot[i]>d)continue;
            if(ans>d-bot[i]){
                ans=d-bot[i];
                step=sum;
            }
        }
        if(!ans)return 1;
        return 0;
    }
    bool operator <(const Sta &b)const{
        return sum>b.sum;
    }
}Tmp;
bool vis[205][205];
int size[3],now[3];
int t;
inline void bfs(){
    memset(vis,0,sizeof(vis));
    ans=inf,step=0;
    priority_queue <Sta> q;
    while(q.size())q.pop();
    q.push(Sta(0,0,c,0));
    vis[0][0]=1;
    int x,y,z,lef,o,p;
    while(q.size()){
        Tmp=q.top();q.pop();
        if(Tmp.update()){
            printf("%d %d
",Tmp.sum,d-ans);
            return ;
        }
        now[0]=Tmp.bot[0],now[1]=Tmp.bot[1],now[2]=Tmp.bot[2],o=Tmp.sum;
        for(ri i=0;i<3;i++){//i倒入j杯 
            for(ri j=0;j<3;j++){
                if(!now[i]||size[j]==now[j]||i==j)continue;
                lef=size[j]-now[j];
                if(now[i]>=lef){
                    now[i]-=lef;
                    now[j]=size[j];
                    if(!vis[now[0]][now[1]]){
                        vis[now[0]][now[1]]=1;
                        q.push(Sta(now[0],now[1],now[2],o+lef));
                    }
                    now[i]+=lef;
                    now[j]-=lef;
                }
                else{
                    p=now[i];
                    now[i]=0;
                    now[j]+=p;
                    if(!vis[now[0]][now[1]]){
                        vis[now[0]][now[1]]=1;
                        q.push(Sta(now[0],now[1],now[2],o+p));
                    }
                    now[i]=p;
                    now[j]-=p;
                }
            }
        }
    }
    printf("%d %d
",step,d-ans);
    return ;
}
int main(){
    read(t);
    while(t--){ 
        read(a),read(b),read(c),read(d);
        size[0]=a,size[1]=b,size[2]=c;
        bfs();
    }
    return 0;
}

以上是关于UVA10603Fill题解--BFS的主要内容,如果未能解决你的问题,请参考以下文章

UVA - 10603 Fill(BFS求最小值问题)

UVa 10603 Fill (暴力BFS+优先队列)

UVA - 10603 Fill(隐式图搜索)

UVA - 10603 Fill(隐式图搜索)

UVA 10603 Fill(正确代码尽管非常搓,网上很多代码都不能AC)

UVa 10603 Fill [暴力枚举路径搜索]