POJ3414 Pots

大概思路:题意是解最少步骤及打印对应步骤。Min求解可以用BFS,但是此题还需记录步骤。

    故用BFS+vector解决此题,第一次TLE,加了visited[105][105]判断后就AC了。

#include<iostream>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;

struct Pot{
    int A,B,steps;
    vector <int >r;
};
char str[6][15]={"FILL(1)","FILL(2)","POUR(2,1)","POUR(1,2)","DROP(1)","DROP(2)"};
int visited[105][105];

void BFS(int a,int b,int c);

int main(){
    int a,b,c;
    cin>>a>>b>>c;
    memset(visited,0,sizeof(visited));
    visited[0][0]=1;
    BFS(a,b,c);
    return 0;
}
void BFS(int a,int b,int c){
    Pot p1,p2;
    p1.A=p1.B=p1.steps=0;
    queue <Pot>q;
    q.push(p1);
    while(!q.empty()){
        p2=q.front();
        if(p2.A==c||p2.B==c){
            cout<<p2.steps<<endl;
            int i;
            for(i=0;i<p2.steps;i++){
              cout<<str[p2.r[i]]<<endl;
            }
            break;
        }
        q.pop();
        p1.steps=p2.steps+1;
        while(!p1.r.empty()){
                p1.r.pop_back();
        }
        for(int i=0;i<p2.steps;i++)
            p1.r.push_back(p2.r[i]);
        //6 case
        if(p2.A<a){
            p1.A=a;
            p1.B=p2.B;
            if(!visited[p1.A][p1.B]) {
                p1.r.push_back(0);//FILL(1)
                q.push(p1);
                p1.r.pop_back();
                visited[p1.A][p1.B]=1;
            }

        }
        if(p2.B<b){
            p1.A=p2.A;
            p1.B=b;
            if(!visited[p1.A][p1.B]){
                p1.r.push_back(1);//FILL(2)
                q.push(p1);
                p1.r.pop_back();
                visited[p1.A][p1.B]=1;
            }

        }
        if(p2.B>0&&p2.A<a){
            p1.A=((p2.A+p2.B)<a?(p2.A+p2.B):a);
            p1.B=((p2.A+p2.B)<a?0:(p2.A+p2.B-a));
            if(!visited[p1.A][p1.B]) {
                p1.r.push_back(2);//POUR(2,1)
                q.push(p1);
                p1.r.pop_back();
                visited[p1.A][p1.B]=1;
            }

        }
        if(p2.A>0&&p2.B<b){
            p1.A=((p2.A+p2.B)<b?0:(p2.A+p2.B-b));
            p1.B=((p2.A+p2.B)<b?(p2.A+p2.B):b);
            if(!visited[p1.A][p1.B]) {
                p1.r.push_back(3);//POUR(1,2)
                q.push(p1);
                p1.r.pop_back();
                visited[p1.A][p1.B]=1;
            }

        }
        if(p2.A>0){
            p1.A=0;
            p1.B=p2.B;
            if(!visited[p1.A][p1.B]) {
                p1.r.push_back(4);//DROP(1)
                q.push(p1);
                p1.r.pop_back();
                visited[p1.A][p1.B]=1;
            }

        }
        if(p2.B>0){
            p1.A=p2.A;
            p1.B=0;
            if(!visited[p1.A][p1.B]) {
                p1.r.push_back(5);//DROP(2)
                q.push(p1);
                p1.r.pop_back();
                visited[p1.A][p1.B]=1;
            }

        }
    }
    if(q.empty()) cout<<"impossible\n";
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值