分红酒
来源:互联网 发布:linux tomcat安装版 编辑:程序博客网 时间:2024/04/27 04:34
问题描述:
有4个红酒瓶子,它们的容量分别是:9升, 7升, 4升, 2升
开始的状态是 [9,0,0,0],也就是说:第一个瓶子满着,其它的都空着。
允许把酒从一个瓶子倒入另一个瓶子,但只能把一个瓶子倒满或把一个瓶子倒空,不能有中间状态。这样的一次倒酒动作称为1次操作。
假设瓶子的容量和初始状态不变,对于给定的目标状态,至少需要多少次操作才能实现?
本题就是要求你编程实现最小操作次数的计算。
输入:最终状态(逗号分隔)
输出:最小操作次数(如无法实现,则输出-1)
输入:
9,0,0,0
应该输出:
0
输入:
6,0,0,3
应该输出:
-1
输入:
7,2,0,0
应该输出:
2
分析:
采用宽度优先遍历,枚举出分酒的每个状态,满足给定条件退出。
#include<cstdio>#include<cstring>#include<cstdlib>#define MAXN 100#define min(a,b) a<b?a:btypedef struct node{ int state[4]; int step;}Node;int vis[MAXN][MAXN][MAXN];int a, b, c, d;int cap[4] = {9,7,4,2};void bfs(){ Node n; n.state[1] = n.state[2] = n.state[3] = 0; //初始化状态 n.state[0] = 9; n.step = 0; Node q[1000]; int front = 0, rear = 1; q[front] = n; vis[n.state[1]][n.state[2]][n.state[3]] = 1; while(front < rear) { Node p = q[front]; //出队 if(p.state[0] == a && p.state[1] == b && p.state[2] == c && p.state[3] == d) { printf("%d\n",p.step); return; } for(int i = 0; i < 4; i++) //枚举倒入一次的状态 { for(int j = 0; j < 4; j++) { if(i == j) continue; Node p1 = p; int count = min(p.state[i],cap[j]-p.state[j]);//判断两瓶子水容量大小 p1.state[i] -= count; p1.state[j] += count; p1.step++; if(!vis[p1.state[1]][p1.state[2]][p1.state[3]]) { vis[p1.state[1]][p1.state[2]][p1.state[3]] = 1; q[rear++] = p1; //入队 } } } front++; } printf("-1\n");}int main(){ memset(vis,0,sizeof(vis)); scanf("%d%d%d",&a,&b,&c); bfs(); return 0;}
0 0
- 分红酒
- 分红酒
- 分红酒
- 分红酒
- 分红酒--蓝桥杯
- 分红酒_蓝桥杯
- 分红酒 - 蓝桥杯 - 已更新
- 分红酒(广度优先搜索)
- 分红酒 (广度优先搜索)
- 蓝桥杯历届决赛之分红酒
- 红酒
- 蓝桥杯软件大赛---分红酒(广度优先搜索)
- 蓝桥杯预赛 分红酒问题 9 7 4 2
- [JAVA][2013蓝桥杯模拟赛 JAVA本科B组][第五题:分红酒]
- 午夜红酒
- 红酒美人
- 红酒常识
- 红酒牛扒
- 【C/C++】int *p[4]与int (*q)[4]的区别
- java.ByteArrayInputStream与ByteArrayOutputStream浅谈
- BZOJ 1861 书架(splay)
- OC_类
- 【C/C++】C/C++ 中二维数组传递的三种方式
- 分红酒
- html常用标签及说明
- BufferedOutputStream和ByteArrayOutputStream区别
- OC_ 常见错误
- float f = new Float(2);
- POJ 1780 Code (欧拉回路+非递归版dfs)
- D. R2D2 and Droid Army(二分加多维线段树查询区间最大值)
- OC_语法
- OC_语法