poj 3414 Pots (bfs)

鏈接:poj 3414

題意:給出了兩個瓶子的容量A,B, 以及一個目標水量C,對A,B可以進行如下操作:

FILL(i)    將瓶i裝滿水

DROP(i)   將瓶i倒空

POUR(i,j) 將瓶i中的水倒入瓶j,此操作後要麼瓶j裝滿水,要麼瓶i爲空

求至少要幾次操作能使A或者B裝的水爲C,並輸出具體操作

分析:可以從6個方面bfs,因爲要輸出具體操作,可以用數組模擬隊列,

並記錄前一次操作的狀態,最後再回溯路徑


#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct stu
{
    int step,a,b,pos;
}que[1010];
int a,b,c,ope[1010],step[1010],x,y,front,rear;
bool vis[105][105];
void fill(int i)
{
    if(i==1)
        x=a;
    else
        y=b;
}
void drop(int i)
{
    if(i==1)
        x=0;
    else
        y=0;
}
void pour(int i,int j)
{
    if(i==1){
        if(x+y>=b){
            x-=b-y;
            y=b;
        }
        else{
            y+=x;
            x=0;
        }
    }
    else{
        if(x+y>=a){
            y-=a-x;
            x=a;
        }
        else{
            x+=y;
            y=0;
        }
    }
}
void is_push(int step,int num)
{
    if(!vis[x][y]){
        que[rear].a=x;        
        que[rear].b=y;
        que[rear].step=step+1;  //記錄步數
        que[rear].pos=front;   //記錄前一次狀態
        ope[rear++]=num;      //當前的操作
        vis[x][y]=true;   //標記爲已訪問
    }
}
int bfs()
{
    int i,num,q[7]={0,110,120,210,220,312,321};  //q數組用來標記執行的操作,以便最後輸出
    struct stu t;
    front=0;
    rear=1;
    memset(vis,0,sizeof(vis));
    vis[0][0]=1;
    que[front].a=que[front].b=0;
    que[front].step=0;
    while(front<rear){
        t=que[front];
        if(t.a==c||t.b==c){
            num=t.step;
            step[num]=front;
            num--;
            while(num){
                step[num]=que[step[num+1]].pos;
                num--;
            }
            return t.step;
        }
        for(i=1;i<=6;i++){
            x=t.a;
            y=t.b;
            switch(i){
                case 1:fill(1);break;
                case 2:fill(2);break;
                case 3:drop(1);break;
                case 4:drop(2);break;
                case 5:pour(1,2);break;
                case 6:pour(2,1);
            }
            is_push(t.step,q[i]);
        }
        front++;
    }
    return -1;
}
int main()
{
    int sum,i,k;
    while(scanf("%d%d%d",&a,&b,&c)!=EOF){
        sum=bfs();
        if(sum==-1){
            printf("impossible\n");
            continue;
        }
        printf("%d\n",sum);
        for(i=1;i<=sum;i++){
            k=ope[step[i]];
            if(k/100==1)
                printf("FILL(%d)\n",k/10%10);
            else if(k/100==2)
                printf("DROP(%d)\n",k/10%10);
            else if(k/100==3)
                printf("POUR(%d,%d)\n",k/10%10,k%10);
        }
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章