POJ - 3414 Pots (kuangbin - 简单搜索)_求只使用上述的两个容器和三种操作,获得恰好 c 升水的最少操作数和操作序列-程序员宅基地

技术标签: 算法  c++  数据结构  bfs  

题目描述(已转换成中文)

  小明给你两个容器,分别能装下A升水和B升水,并且可以进行以下操作:
  FILL(i) 将第i个容器从水龙头里装满(1 ≤ i ≤ 2);
  DROP(i) 将第i个容器抽干
  POUR(i,j) 将第i个容器里的水倒入第j个容器(这次操作结束后产生两种结果,一是第j个容器倒满并且第i个容器依旧有剩余,二是第i个容器里的水全部倒入j中,第i个容器为空)
  现在要求你写一个程序,来找出能使其中任何一个容器里的水恰好有C升,找出最少操作数并给出操作过程

输入格式

  有且只有一行,包含3个A,B,C(1<=A,B<=100,C<=max(A,B))

输出格式

  第一行包含一个数表示最小操作数K
  随后K行每行给出一次具体操作,如果有多种答案符合最小操作数,输出他们中的任意一种操作过程,如果你不能使两个容器中的任意一个满足恰好C升的话,输出“impossible”

输入输出样例
输入

3 5 4

输出

6
FILL(2)
POUR(2,1)
DROP(1)
POUR(2,1)
FILL(2)
POUR(2,1)

题目链接

分析:

  这道题要用到暴搜的思想,我用的是bfs解决问题,首先由题意得我们每一次操作都有6中选择:把i容器倒满、把j容器倒满、把i容器抽干、把j容器抽干、把i容器的水倒出j容器、把j容器的水倒入i容器。定义一个node结构体,结构体中,x和y分别表示每一次操作之后a容器和b容器分别有多少水量,ans表示进行的操作数,整型数组u表示前i次操作是什么,前i - 1次的具体操作是保存在刚从队首被弹出的节点里(队首元素的u数组中u[0] ~ u[i - 1]分别表示即保留了下标是前i - 1的数组元素,接着更新u[i]记录这一轮是什么操作),这样就能实现一个节点保存了前面的i次具体操作,主函数先输入两个容器的体积a和b,以及想要得到的水量c,另外,还要在主函数外定义一个vis二维数组,标记某种情况是否出现过,vis[i][j] == 1代表容器a中有i升水,容器b中有j升水,避免后续再次进行的操作得到的结果之前出现过,最后得到的答案不是最小操作次数。
  调用bfs函数,把容器a和b水量都为零的初始情况压入队列,不断弹出队首元素,对队首元素进行处理,把队首节点的u数组(保存了之前的具体操作)的前i - 1个元素都赋值给新的节点,接着u[i]保存的是最新操作,更新步长并把节点压入队列;若遇到符合预期情况的水量,则输出步长(操作次数),并依次输出u数组对应的操作;若队列已经为空,还没有遇到符合预期情况的水量,则输出impossible。

这道题需要注意的地方:

  对于每轮操作,我们有6种选择,并由u数组记录之前的具体操作,我们定义f[6][10]= {“FILL(1)”, “FILL(2)”, “POUR(1,2)”, “POUR(2,1)”, “DROP(1)”, “DROP(2)”},u数组的元素下标只要取0 ~ 5就能正序保存从初始到当前的具体操作,当遇到符合预期情况的水量时,依次输出u数组中对应的操作printf("%s\n", f[n.u[i]])。

代码如下:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long LL;
int vis[105][105];
int flag;
int a, b, c, i;
char f[6][10]= {
    "FILL(1)", "FILL(2)", "POUR(1,2)", "POUR(2,1)", "DROP(1)", "DROP(2)"};
int read(){
    
	int x, f = 1;
	char ch;
	while(ch = getchar(), ch < '0' || ch > '9') if(ch == '-') f = -1;
	x = ch - '0';
	while(ch = getchar(), ch >= '0' && ch <= '9') x = x * 10 + ch - 48;
	return x * f;
}
struct node{
    
	int x, y, ans;
	int u[105];
};
void bfs(){
    
	queue <node> s;
	node n, m;
	n.x = 0;
	n.y = 0;
	n.ans = 0;
	n.u[0] = 0;
	s.push(n);
	vis[0][0] = 1;
	while(!s.empty()){
    
		n = s.front();
		s.pop();
		if(n.x == c || n.y == c){
    
			flag = 1;
			printf("%d\n", n.ans);
			for(i = 1; i <= n.ans; i++){
    
				printf("%s\n",  f[n.u[i]]);
			}
			return;
		}
		for(i = 0; i < 6; i++){
    
			m.ans = n.ans + 1;
			m.x = 0;
			m.y = 0;
			for(int j = 1; j <= n.ans; j++) m.u[j] = n.u[j];
			m.u[m.ans] = i;
			if(i == 0 && n.x != a){
    						//FILL(1)
				m.x = a;
				m.y = n.y;
			}
			else if(i == 1 && n.y != b){
    				//FILL(2)
				m.y = b;
				m.x = n.x;
			}
			else if(i == 2 && n.x && n.y != b){
    			//POUR(1,2)
				if(n.x + n.y > b){
    
					m.x = n.x + n.y - b;
					m.y = b;
				}
				else{
    
					m.x = 0;
					m.y = n.x + n.y;
				}
			}
			else if(i == 3 && n.y && n.x != a){
    			//POUR(2,1)
				if(n.x + n.y > a){
    
					m.x = a;
					m.y = n.x + n.y - a;
				}
				else{
    
					m.y = 0;
					m.x = n.x + n.y;
				}
			}
			else if(i == 4 && n.x){
    						//DROP(1)
				m.x = 0;
				m.y = n.y;
			}
			else if(i == 5 && n.y){
    						//DROP(2)
				m.y = 0;
				m.x = n.x;
			}
			if(!vis[m.x][m.y]){
    
				vis[m.x][m.y] = 1;
				s.push(m);
			}
		}
	}
}
int main(){
    
	a = read(), b = read(), c = read();
	bfs();
	if(!flag) printf("impossible\n");
	return 0;
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_46215084/article/details/108857791

智能推荐

can't return outside function or method解决方法_return outside method-程序员宅基地

文章浏览阅读4.5k次。今天写web项目作业时,发现jsp中“Cannot return from outside a function or method” 提示return出错,百度了一下,网上说这是myeclipse的一个bug,去掉return就好了,去掉之后果然不报错,但是之后发现onSubmit()不能阻止表单提交,再百度之,原来这个return还真不能去掉。以下就是今天错误的解决方法 1_return outside method

python爬取研究生招生网招生信息_考研信息api-程序员宅基地

文章浏览阅读7.2k次,点赞3次,收藏64次。import requestsfrom bs4 import BeautifulSoupfrom pandas.core.frame import DataFrameimport reimport timeclass Graduate: def __init__(self, province, category): self.head = { ..._考研信息api

web结课作业的源码 WEB静态网页作业模板 大学生个人主页博客网页代码 dw个人网页作业成品简单页面-程序员宅基地

文章浏览阅读330次,点赞8次,收藏10次。HTML实例网页代码, 本实例适合于初学HTML的同学。该实例里面有设置了css的样式设置,有div的样式格局,这个实例比较全面,有助于同学的学习,本文将介绍如何通过从头开始设计个人网站并将其转换为代码的过程来实践设计。 精彩专栏推荐 【作者主页——获取更多优质源码】 【学习资料/简历模板/面试资料/ 网站设计与制作】 【web前端期末大作业——毕设项目精品实战案例】---@[TOC](文章目录)一、网页介绍1 网页简介:此作品为学生个人主

ICML2019|深度学习鼻祖之一Bengio提出并开源图马尔科夫神经网络-程序员宅基地

文章浏览阅读724次。Meng Qu,Yoshua Bengio,Jian TangMontreal Institute for Learning Algorithms (MILA), Uni..._马尔可夫 图神经网络

【Scikit-Learn】初试开源机器学习工具_# author: gael varoquaux <gael.varoquaux@normalesu-程序员宅基地

文章浏览阅读904次。啊好久没用Markdown以外的编辑器了,这次随性一点就用xhEditor吧~嘛,写的确实也挺随(luan)性(xie)的23333$ pip install -U scikit-learn$ wget http://scikit-learn.org/stable/_downloads/plot_spectral_biclustering.py$ wget http://sciki_# author: gael varoquaux

VMware vSphere 6 序列号大全-程序员宅基地

文章浏览阅读1.7w次,点赞4次,收藏11次。转载自 http://www.i5i6.net/post/190.htmlvSphere 6 HypervisorHY0XH-D508H-081U8-JA2GH-CCUM24C4WK-8KH8L-H85J0-UHCNK-8CKQ8NV09R-2W007-08D38-CA956-33U28JU400-6EK4L-080V9-QT8EP-2KAQ2vSphere 6 Hypervisor for E..._esxi 6.0 序列号

随便推点

B-tree/B+tree/B*tree-程序员宅基地

文章浏览阅读528次。B~树 1.前言:动态查找树主要有:二叉查找树(Binary Search Tree),平衡二叉查找树(Balanced Binary Search Tree),红黑树 (Red-Black Tree ),B-tree/B+-tree/ B*-tree (B~Tree)。前三者是典型的二叉查找树结构,其查找的时间复杂度O(log2N)与树的深度相关,那么

一个文科生从零到进入大厂的感悟(3小时掌握一门编程语言)_文科生进在华为云工作需要学编程代码-程序员宅基地

文章浏览阅读527次。你学编程的方法对吗?你是否手写代码?你是否死记硬背?你是否把学文科的方法应用到编程上?你是否前面学后面忘?你是否在抱怨编程难学?如果你遇到上面这些问题,很遗憾的告诉你,你学习的方法错了。这些问题我都遇到过,我一开始学编程的时候,感觉可难了,当时就是照着别人的视频和教程一点点的学,一点点的敲代码,记忆,可是几个月过去了又忘光了,不断重复这种死循环。直到有一天,我认识了一位前辈,我发现,我错了,编程不是这么学的。1.不要看视频学习那编程应该怎么学呢?首先我不建议你去看视频学习,因为这种学_文科生进在华为云工作需要学编程代码

Echarts基础-安装语法高亮插件&less-rem转换动态适配大小_echarts无法rem转换-程序员宅基地

文章浏览阅读1k次,点赞33次,收藏13次。Echarts是一个功能强大的JavaScript开源可视化库,专门用于创建各种图表和数据可视化。丰富的图表类型:Echarts提供了包括折线图、柱状图、散点图、饼图、雷达图、地图等多种常见的图表类型,满足不同的数据展示需求。兼容性良好:它可以流畅运行在PC和移动设备上,并且兼容多种浏览器,如IE8/9/10/11,Chrome,Firefox,Safari等。底层依赖ZRender:Echarts底层依赖于矢量图形库ZRender,这使得其能够提供直观且交互性强的数据可视化效果。_echarts无法rem转换

Spring框架以及源码学习_spring框架源码-程序员宅基地

文章浏览阅读769次。一、Spring注解驱动开发1.容器—组件注册-@Configuration&@Bean给容器中注册组件—组件注册-@ComponentScan-自动扫描组件&指定扫描规则—组件注册-自定义TypeFilter指定过滤规则—组件注册-@Scope-设置组件作用域—组件注册-@Lazy-bean懒加载—组件注册-@Conditional-按照条件注册bean...................._spring框架源码

Vue播放器之vue-video-player及其问题_vue mp4编码-程序员宅基地

文章浏览阅读3k次。Vue播放器之vue-video-player及其问题一、使用vue-video-player1.安装 npm install vue-video-player --save2.main.js引入vue-video-playerimport VideoPlayer from 'vue-video-player'require('video.js/dist/video-js.css')require('vue-video-player/src/custom-theme.css')Vue.u_vue mp4编码

Qt 杂项(Qwt、样式等)_qwt 样式-程序员宅基地

文章浏览阅读608次。QwtDial 的指针是由QwtDialNeedle类绘制的,自定指针也就是实现QwtDialNeedle的子类继承QwtDialNeedle只需要实现drawNeedle函数i < 4;i++ )滑块是通过drawHandle函数绘制;可以通过一个函数指针,将外部绘制滑块的逻辑引入,替换默认绘制逻辑函数指针定义(qwt_slider.h):主要参数:handleRect,绘制滑块的区域,根据handleRect的坐标范围进行自定义绘制。_qwt 样式

推荐文章

热门文章

相关标签