ACM第二次練習—1017

題意:有一瓶體積爲S的可樂,另外有兩個空的體積分別是n,m的杯子,問:能否平分可樂,如果能輸出最少倒多少次才能平分。

思路:明確目標狀態是有兩個杯子都是S/2,那麼,只要找到這狀態就行,可從開始狀態出發,把每一種出現的狀態都找出來,並保存,直到找到這狀態.當然,重複狀態要過慮。用到的是廣搜。

感想:例題不多說。

代碼:

#include <stdio.h>  
#define MAXS 110  
#include <string.h>  
#include<queue>  
using namespace std;  
typedef struct E{  
    int a,b,c,t;  
}E;  
int mark[MAXS][MAXS][MAXS];  
queue < E > Q;  
void AtoB(int &a,int sa,int &b,int sb)  
{  
    int temp=sb-b;  
    if(temp>a){b+=a;a=0;}  
    else {a-=temp;b=sb;}  
}  
bool isok(E temp,int maxc)  
{  
    maxc>>=1;  
    return(temp.a==maxc&&temp.b==maxc||temp.a==maxc&&temp.c==maxc||temp.b==maxc&&temp.c==maxc);  
}  
int main()  
{  
    int maxa,maxb,maxc;  
    while(~scanf("%d %d %d",&maxc,&maxa,&maxb)&&maxc)  
    {  
        if(maxc&1){puts("NO");continue;}  
        memset(mark,1,MAXS*MAXS*MAXS*sizeof(int));  
        while(Q.empty()==false)Q.pop();  
        E now,temp;  
        int flag;  
        now.a=now.b=now.t=0;  
        now.c=maxc;flag=0;  
        mark[0][0][maxc]=0;  
        Q.push(now);  
        while(Q.empty()==false&&flag==0)  
        {  
            now=Q.front();  
            Q.pop();  
            now.t++;  
            temp=now;  
            AtoB(temp.c,maxc,temp.b,maxb);  
            if(mark[temp.a][temp.b][temp.c])  
            {  
                mark[temp.a][temp.b][temp.c]=0;  
                if(flag=isok(temp,maxc))break;  
                Q.push(temp);  
            }  
            temp=now;  
            AtoB(temp.a,maxa,temp.b,maxb);  
            if(mark[temp.a][temp.b][temp.c])  
            {  
                mark[temp.a][temp.b][temp.c]=0;  
                if(flag=isok(temp,maxc))break;  
                Q.push(temp);  
            }         
            temp=now;  
            AtoB(temp.a,maxa,temp.c,maxc);  
            if(mark[temp.a][temp.b][temp.c])  
            {  
                mark[temp.a][temp.b][temp.c]=0;  
                if(flag=isok(temp,maxc))break;  
                Q.push(temp);  
            }         
            temp=now;  
            AtoB(temp.b,maxb,temp.a,maxa);  
            if(mark[temp.a][temp.b][temp.c])  
            {  
                mark[temp.a][temp.b][temp.c]=0;  
                if(flag=isok(temp,maxc))break;  
                Q.push(temp);  
            }             
            temp=now;  
            AtoB(temp.b,maxb,temp.c,maxc);  
            if(mark[temp.a][temp.b][temp.c])  
            {  
                mark[temp.a][temp.b][temp.c]=0;  
                if(flag=isok(temp,maxc))break;  
                Q.push(temp);  
            }    www.2cto.com
            temp=now;  
            AtoB(temp.c,maxc,temp.a,maxa);  
            if(mark[temp.a][temp.b][temp.c])  
            {  
                mark[temp.a][temp.b][temp.c]=0;  
                if(flag=isok(temp,maxc))break;  
                Q.push(temp);  
            }  
        }  
        if(flag)printf("%d\n",now.t);  
        else puts("NO");  
    }  
    return 0;  
}  
 

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