三个水杯

来源:互联网 发布:有名的网络女明星 编辑:程序博客网 时间:2024/04/25 13:36

三个水杯

时间限制:1000 ms  |  内存限制:65535 KB
难度:4
描述
给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子。三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算。现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数。
输入
第一行一个整数N(0<N<50)表示N组测试数据
接下来每组测试数据有两行,第一行给出三个整数V1 V2 V3 (V1>V2>V3 V1<100 V3>0)表示三个水杯的体积。
第二行给出三个整数E1 E2 E3 (体积小于等于相应水杯体积)表示我们需要的最终状态
输出
每行输出相应测试数据最少的倒水次数。如果达不到目标状态输出-1
样例输入
26 3 14 1 19 3 27 1 1
样例输出
3-1
刚刚开始做搜索,这个题之前一直过不了是因为在清空队列的时候把while写成了if= = 低级错误。。。。
这是个典型的广搜的题。
#include <stdio.h>#include <string.h>#include <queue>#define SIZE 110using namespace std;struct water{int a[3];int step;};water s;bool visit[SIZE][SIZE][SIZE];//标记数组int six[6][2]={{0,1},{0,2},{1,0},{1,2},{2,0},{2,1}};//六种倒水的方法int e1, e2, e3;//记录最终状态queue<water>q;int del (water *c, int x, int y)//把x的水倒进y{if(c->a[x] != 0 && c->a[y] != s.a[y])//只有当x不是空而且y不是满的时候才执行,不然直接返回0{if(c->a[x] + c->a[y] <= s.a[y])//如果x可以把全部水都倒给y{c->a[y] += c->a[x];c->a[x] = 0;//x倒完了}else//把x的水都到给y的话y会溢出{c->a[x] -= s.a[y] - c->a[y];c->a[y] = s.a[y];//将y倒满,但是注意一定不能与上面的式子写颠倒了}if(visit[c->a[0]][c->a[1]][c->a[2]] == 0){visit[c->a[0]][c->a[1]][c->a[2]] = 1;return 1;}}return 0;}int bfs(water start){int i;//queue<water>q;q.push(start);visit[start.a[0]][start.a[1]][start.a[2]] = 1;while(!q.empty()){water e = q.front();q.pop();if(e.a[0] == e1 && e.a[1] == e2 && e.a[2] == e3){//printf("%d\n", e.step);return e.step;}water ex;for(i = 0; i < 6; i++){ex = e;if(del(&ex, six[i][0], six[i][1])){ex.step = e.step + 1;//printf("a[0] = %d, a[1] = %d, a[2] = %d\n", ex.a[0], ex.a[1], ex.a[2]);q.push(ex);}}}//printf("!!\n");return -1;}int main (void){int n;scanf("%d", &n);while (n--){scanf("%d %d %d", &s.a[0], &s.a[1], &s.a[2]);scanf("%d %d %d", &e1, &e2, &e3);memset(visit, 0, sizeof(visit));water start;start.a[0] = s.a[0];start.a[1] = start.a[2] = start.step = 0;while(!q.empty()){q.pop();}int a = bfs(start);printf("%d\n", a);}return 0;}
0 0
原创粉丝点击