http://poj.org/problem?id=3414

题意 : 大意是说给你两个杯子的体积和一个目标体积,a,b,c,通过对a,b进行6种操作,调出c体积的水,6种操作分别是把a倒满,把b倒满,把a弄成空的,把b弄成空的,把a里边的倒到b里,把b里边的水倒到a里;

思路 : 算不上说多难,反正就是六种操作

#include<cstdio>
#include<cstring>
#include<iostream>
const int maxn = 1001000 ;
using namespace std;
int a,b,c;
int r,l;
int vis[110][110];
struct node
{
    int cup1,cup2,step;//两个杯子,走的步数
    int mark;//进行标记,方便输出
    int prev;//记录前一个状态
}ch[maxn],sh,zh;
int stepp,s;
void bfs()
{
    /*初始化*/
    ch[0].cup1 = 0 ;
    ch[0].cup2 = 0 ;
    ch[0].step = 0 ;
    ch[0].mark = 0 ;
    l = 0,r = 1 ;
    vis[0][0] = 1 ;
    /*队列模拟*/
    while(l<r)
    {
        sh = ch[l] ;
        if(sh.cup1 == c||sh.cup2 == c)//结束标志
        {
            stepp = sh.step ;
            s = l ;//输出时寻找前驱的
            return ;
        }
        if(sh.cup1 != a)//将杯1倒满
        {
            zh.cup1 = a ;
            zh.cup2 = sh.cup2 ;
            zh.step = sh.step+1 ;
            zh.prev = l ;
            zh.mark = 1 ;
            if(!vis[zh.cup1][zh.cup2])
            {
                vis[zh.cup1][zh.cup2] = 1 ;
                ch[r++] = zh ;//这个状态存到ch数组里
            }
        }
        if(sh.cup2 != b)//将杯2装满
        {
            zh.cup2 = b ;
            zh.cup1 = sh.cup1 ;
            zh.step = sh.step+1 ;
            zh.mark = 2 ;
            zh.prev = l;
            if(!vis[zh.cup1][zh.cup2])
            {
                vis[zh.cup1][zh.cup2] = 1 ;
                ch[r++] = zh ;
            }
        }
        if(sh.cup1 != 0)//将杯1倒空
        {
            zh.cup1 = 0 ;
            zh.cup2 = sh.cup2 ;
            zh.mark = 3 ;
            zh.prev = l;
            zh.step = sh.step+1 ;
            if(!vis[zh.cup1][zh.cup2])
            {
                vis[zh.cup1][zh.cup2] = 1 ;
                ch[r++] = zh ;
            }
        }
        if(sh.cup2 != 0)//将杯2倒空
        {
            zh.cup2 = 0 ;
            zh.cup1 = sh.cup1;
            zh.mark = 4 ;
            zh.prev = l;
            zh.step = sh.step+1 ;
            if(!vis[zh.cup1][zh.cup2])
            {
                vis[zh.cup1][zh.cup2] = 1 ;
                ch[r++] = zh ;
            }
        }
        if(sh.cup1 != 0)//将杯1水倒到杯2里
        {
            if(sh.cup1 >= b-sh.cup2)
            {
                zh.cup1 = sh.cup1-(b-sh.cup2) ;
                zh.cup2 = b ;
            }
            else
            {
                zh.cup2 = sh.cup1+sh.cup2 ;
                zh.cup1 = 0 ;
            }
            zh.step = sh.step+1 ;
            zh.mark = 5 ;
            zh.prev = l ;
            if(!vis[zh.cup1][zh.cup2])
            {
                vis[zh.cup1][zh.cup2] = 1 ;
                ch[r++] = zh ;
            }
        }
        if(sh.cup2 != 0)//将杯2水倒到杯1里
        {
            if(sh.cup2 >= a-sh.cup1)
            {
                zh.cup2 = sh.cup2- (a-sh.cup1);
                zh.cup1 = a ;
            }
            else
            {
                zh.cup1 = sh.cup1+sh.cup2 ;
                zh.cup2 = 0 ;
            }
            zh.step = sh.step+1 ;
            zh.mark = 6 ;//进行标记
            zh.prev = l ;
            if(!vis[zh.cup1][zh.cup2])
            {
                vis[zh.cup1][zh.cup2] = 1 ;
                ch[r++] = zh ;
            }
        }
        l++ ;
    }
}
void printff(int i)
{
    if(i == 0)
    return ;
    printff(ch[i].prev) ;
    if(ch[i].mark == 1) printf("FILL(1)\n");
    else if(ch[i].mark == 2) printf("FILL(2)\n");
    else if(ch[i].mark == 3) printf("DROP(1)\n");
    else if(ch[i].mark == 4) printf("DROP(2)\n");
    else if(ch[i].mark == 5) printf("POUR(1,2)\n");
    else if(ch[i].mark==6) printf("POUR(2,1)\n");
}
int main()
{
    while(scanf("%d %d %d",&a,&b,&c)!=EOF)
    {
        stepp=0;
        memset(vis,0,sizeof(vis));
        bfs();
        if(stepp != 0)
        {
            printf("%d\n",stepp);
            printff(s);
        }
        else printf("impossible\n");
    }
    return 0;
}
View Code

 

posted on 2013-08-30 11:52  枫、  阅读(196)  评论(0编辑  收藏  举报