10603 - Fill uva 隐式图的遍历

比较简单的隐式图搜索吧,建立状态结构体,然后暴力搜索出来,思路很明确,个人认为比较水的题了=-= 


第一次读错题了,但是AC了,之后UVA加了几组数据WA了,改了一次又对了
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cmath>
using namespace std;
#define MAX_SIZE 500000 + 10
struct State
{
    int x;/*第一个杯子里的水*/
    int y;/*第二个杯子里的水*/
    int z;/*第三个杯子里的水*/
    int step;
    /*达到这个状态花费的步数*/
    friend bool operator <(State a,State b){
           if(a.step < b.step)
              return true;
           else
              return false;
       }
};
int v[3];/*杯子的容量*/
State St[MAX_SIZE];
int End_State;
int front,back;
int Steps,nearly,Cup;
int  exchange(int &x,int &y,int n){ /*返回转移水的数量*/
    /*将水从x倒向y,n为水杯的最大容量*/
    int t=x-(n-y);
    if(t > 0){
        t=n-y;
        x=x-(n-y);
        y=n;
        return t;
    }
    else{
        t=x;
        y=(x+y);
        x=0;
        return t;
    }
}
bool Judge_ever(int x,int y,int z,int s){
     for(int i=0;i < back;i++){
         if(St[i].x==x && St[i].y==y && St[i].z==z && St[i].step <= s)
            return true;
     }
     return false;/*这个状态不存在*/
}
void Judge_Nearly(int x,int y,int z,int step){
    int a=End_State-x;
    int b=End_State-y;
    int c=End_State-z;
    /*a,b,c代表他们和最终距离的差*/
        if(a<=nearly && a>=0){
            if(a < nearly){
                Steps = step;
                nearly=a;
            }
            else{
                if(Steps > step){
                    Steps=step;
                }
            }
            Cup=x;
        } /*先比较状态是否接近,状态一样的话取最小的步数*/
        if(b <= nearly && b>=0){
            if(b < nearly){
                Steps =step;
                nearly=b;
            }
            else{
                if(Steps>step){
                    Steps=step;
                }
            }
            Cup=y;
        }
        if(c<=nearly && c>=0){
            if(c<nearly){
                Steps =step;
                nearly=c;
            }
            else{
                if(Steps>step){
                    Steps=step;
                }
            }
            Cup=z;
        }
}
void bfs(){
    front=0,back=0;
    Steps=0;
    nearly=1<<30;/*最接近目标的值*/
    St[back].x=0;
    St[back].y=0;
    St[back].z=v[2];
    St[back].step=0;
    back++;
    while(front < back){
        int sx=St[front].x;
        int sy=St[front].y;
        int sz=St[front].z;
        int ss=St[front].step;

        /*三杯水的状态 + 走到该状态的步数*/
        front++;
        Judge_Nearly(sx,sy,sz,ss);
        /*如果有正好相等的返回这个步数*/
        for(int d=0;d<6;d++){/*模拟倒水的状态*/
            int x=sx;
            int y=sy;
            int z=sz;
            int step=ss;
                 if(d==0) step+=exchange(x,y,v[1]);
            else if(d==1) step+=exchange(x,z,v[2]);
            else if(d==2) step+=exchange(y,x,v[0]);
            else if(d==3) step+=exchange(y,z,v[2]);
            else if(d==4) step+=exchange(z,x,v[0]);
            else if(d==5) step+=exchange(z,y,v[1]);
            if(!Judge_ever(x,y,z,step)){
                   St[back].x=x;
                   St[back].y=y;
                   St[back].z=z;
                   St[back].step=step;
                   back++;
               }
        }
    }
}
int main()
{
    int N;
    scanf("%d",&N);
    for(int cases=1;cases<=N;cases++){
        for(int i=0;i<3;i++)
        scanf("%d",&v[i]);
        scanf("%d",&End_State);
        bfs();
        printf("%d %d\n",Steps,Cup);
    }
    return 0;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值