分红酒
来源:互联网 发布:郭天祥51单片机pdf 编辑:程序博客网 时间:2024/04/19 07:20
有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
当初比赛的时候做的这道题,那时候还没有学习搜索。当时竟然想要用枚举。
可想而知,全是泪水啊。
回来,就学习了大牛的搜索思路。总算是做出来了。
思路:其实就是模拟倒酒的过程,有a,b,c,d四个酒杯,然后有a->b,a->c,a->d,b>a,b->c,b->d........这12种倒酒方式。
在搜索的过程中,要注意有几种情况不能倒酒:
1、a杯中的酒不能倒在a杯中。
2.a杯为空,不能倒酒
3、a->b,如果b杯已满,不能倒酒。
最后再利用一个四位数组,来记录已经经历过的状态。
View Code
1 #include<iostream> 2 #include<queue> 3 using namespace std; 4 5 typedef struct 6 { 7 int now[4]; 8 int step; 9 }state;10 int full[4] = {9 , 7 , 4 , 2};11 int vis[10][8][5][3]; //用来判断是否是已经记录的状态12 13 int bfs(state& temp , int i , int j)14 {15 if(i == j) return 0; //i中的水不能倒在i中16 if(temp.now[i] == 0) return 0; //i中没有水,不能操作17 if(temp.now[j] == full[j]) return 0; //j中水已满,不能操作18 if(temp.now[i] + temp.now[j] <= full[j]) //进入倒水环节19 {20 temp.now[j] = temp.now[j] + temp.now[i]; //将i中的水全部倒入j中 21 temp.now[i] = 0;22 }23 else //将j倒满24 {25 temp.now[i] = temp.now[i] - (full[j] - temp.now[j]);26 temp.now[j] = full[j];27 }28 if(vis[temp.now[0]][temp.now[1]][temp.now[2]][temp.now[3]])29 {return 0;}30 else vis[temp.now[0]][temp.now[1]][temp.now[2]][temp.now[3]] = 1;31 temp.step++;32 return 1;33 }34 int main()35 {36 int end[4]; //需要输入的最后状态37 int i , j , flag;38 while(cin>>end[0]>>end[1]>>end[2]>>end[3])39 {40 queue<state>q;41 flag = 0;42 memset(vis , 0 , sizeof(vis));43 if(end[0]+end[1]+end[2]+end[3]!=9) //非法状态44 {cout<<"-1"<<endl;flag = 1;}45 if(end[0]>full[0]||end[1]>full[1]||end[2]>full[2]||end[3]>full[3]) 46 {cout<<"-1"<<endl;flag = 1;} //非法状态47 state star; //初始状态 初始化48 star.now[0] = 9;49 star.now[1] = 0;50 star.now[2] = 0;51 star.now[3] = 0;52 star.step = 0;53 q.push(star); //将初始状态压入队列54 while(!q.empty())55 {56 state temp = q.front();57 q.pop();58 if(temp.now[0]==end[0]&&temp.now[1]==end[1]&&temp.now[2]==end[2]&&temp.now[3]==end[3])59 {60 flag = 1;61 printf("%d\n" , temp.step);62 break;63 }64 for(i = 0; i < 4; i++)65 {66 for(j = 0; j < 4; j++)67 {68 state temp2 = temp;69 if(bfs(temp2 , i , j))70 q.push(temp2);71 }72 }73 }74 if(!flag) cout<<"-1"<<endl;75 }76 return 0;77 }
0 0
- 分红酒
- 分红酒
- 分红酒
- 分红酒
- 分红酒--蓝桥杯
- 分红酒_蓝桥杯
- 分红酒 - 蓝桥杯 - 已更新
- 分红酒(广度优先搜索)
- 分红酒 (广度优先搜索)
- 蓝桥杯历届决赛之分红酒
- 红酒
- 蓝桥杯软件大赛---分红酒(广度优先搜索)
- 蓝桥杯预赛 分红酒问题 9 7 4 2
- [JAVA][2013蓝桥杯模拟赛 JAVA本科B组][第五题:分红酒]
- 午夜红酒
- 红酒美人
- 红酒常识
- 红酒牛扒
- iOS-Runtime-Headers
- 安装Eclipse Maven插件的几种方法
- hdu——2603——0 or 1
- Cluster Analysis 的 评估方法 Evaluation Methods(Apply For Bioinformatics)
- 柷湢祈湢骉航洤軆岼鮟
- 分红酒
- python django安装
- 第二周作业1——判断一个正整数是否为质数的算法
- java垃圾回收机制
- 深拷贝和浅拷贝的区别是什么?你会如何使用它们?
- WORK_QUEUE_ITEM 介绍
- 遇到的ssh问题汇总
- java 实验一
- 优先队列水题