[算法入门经典] 例题7-3 倒水问题 | HDU 1495

来源:互联网 发布:奢侈品软件哪个最好 编辑:程序博客网 时间:2024/05/16 01:22

以前看到这个题,没有思路,今天回过头看了一下,就是广搜当前状态下能变成的所有状态。

题目需要打印倒水的过程,那么我们应该在结构体里加入前驱变量。

结合书上的图,我们就可以运用广搜解决这个问题了。

为什么标记数组不用三维的? 因为总水数一定,当A,B两个杯子的水相同,那么C一定相同。

HDU 1495 和这个例题很相似哦~

附上代码:

#include <stdio.h>#include <string.h>#include <queue>using namespace std;int visit[1000][1000], aa[3], x;struct ak{    int len;        //步数    int b[3];       //3个水杯的当前状态    int front;      //结构体前驱下标    int arr;        //结构体当前下标}s[1000001], temp, temp2;queue<ak> qq;void gao(int t){    if(t == -1)        return ;    gao(s[t].front);    if(s[t].front != -1)    {        printf(" -> ");    }    printf("(");    for(int i = 0; i < 3; i++)    {        printf(i ? ",%d" : "%d", s[t].b[i]);    }    printf(")");}void bfs(){    int cnt = 0;    while(!qq.empty())    {        temp = qq.front();        temp.arr = cnt;        s[cnt++] = temp;        for(int i = 0; i < 3; i++)        {            if(temp.b[i] == x)            {                printf("最少需要倒%d次,步骤为:\n", temp.len);                gao(temp.arr);  //递归调用输出倒水过程                return ;            }        }        qq.pop();        for(int i = 0; i < 3; i++)        {            for(int j = 0; j < 3; j++)            {                if(i != j)                {                    int tem = aa[j] - temp.b[j]; //计算b[j]杯子还能容纳多少水                    temp2 = temp;                    if(temp.b[i] && tem)         //如果b[i]杯子有水 并且 b[j]杯子还能倒入水                    {                        if(temp.b[i] > tem)      //如果b[i]杯子的水能不能全部倒入b[j]杯子,                        {                        //那么b[i]杯子会剩水,b[j]变满                            temp2.b[i] -= tem;                            temp2.b[j] = aa[j];                        }                        else                     //否则b[i]杯子为空,b[j]杯子的水增加了b[i]                        {                            temp2.b[j] += temp2.b[i];                            temp2.b[i] = 0;                        }                        temp2.front = temp.arr;                        if(!visit[temp2.b[0]][temp2.b[1]])                        {                            visit[temp2.b[0]][temp2.b[1]] = 1;                            ++temp2.len;                            qq.push(temp2);                        }                    }                }            }        }    }}void init(){    memset(visit, 0, sizeof(visit));    visit[aa[0]][0] = 1;    s[0].b[0] = aa[0];    s[0].b[1] = s[0].b[2] = 0;    s[0].len = 0;    s[0].front = -1;    qq.push(s[0]);}int main(){    while(~scanf("%d %d %d", &aa[0], &aa[1], &aa[2]))    {        scanf("%d", &x);    //输入顺序:a,b,c,x        init();             //初始化调用        bfs();        while(!qq.empty())        {            qq.pop();       //执行结束后队列容器内可能有剩余元素,要清空        }    }    return 0;}




0 0
原创粉丝点击