week2 B - Pour Water

2023-12-15 03:48
文章标签 week2 water pour

本文主要是介绍week2 B - Pour Water,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

问题描述:

倒水问题 “fill A” 表示倒满A杯,"empty A"表示倒空A杯,“pour A B” 表示把A的水倒到B杯并且把B杯倒满或A倒空,同理,“fill B” 表示倒满B杯,"empty B"表示倒空B杯,“pour B A” 表示把B的水倒到A杯并且把A杯倒满或B倒空。现有两个容量为A,B的杯子,无限水,如果要得到C容积的水,应该怎样操作?

Input:
输入包含多组数据。每组数据输入 A, B, C 数据范围 0 < A <= B 、C <= B <=1000 、A和B互质。

Output:
你的程序的输出将由一系列的指令组成。这些输出行将导致任何一个罐子正好包含C单位的水。每组数据的最后一行输出应该是“success”。输出行从第1列开始,不应该有空行或任何尾随空格。

解题思路:

深究原理,此题与迷宫路径相似,将状态用坐标表示,从起始状态到目的状态,中间经过一系列不同的状态,而由一个状态变为另一种状态,只有问题描述中的六种方法,故思考得,要记录每一状态的前一状态以及由何种方法转变。采用深度优先搜索(BFS)方法把从初始状态能够到达的不同状态入队列,直到达到目标状态或队列为空。

主要的数据结构:
① 方法标记二维数组sign——表示当前状态由前一状态经何种转变而来。0表示该状态未到达,1表示该点为初始状态,2、3、4、5、6、7分别对应各函数,即该状态由该方法转变而来,8对应目标状态。
② 标记当前状态的前一状态的pair<int,int>二维数组r——用坐标表示状态,记录该状态的前一状态。

步骤:(类似树的按层遍历)

  1. 访问初始点(sx,sy),并将其标记为已访问过,sign置为1。
  2. 访问(sx,sy)的所有未被访问过可到达的状态点,并均标记为已访问过,即sign置为相应方法,前一坐标置为(sx,sy),将这些点加入到队列中。
  3. 再按照队列中的次序,访问每一个顶点(sx,sy)的所有未被访问过可到达的状态点,并做上相应标记,加入到队列中,依此类推。
  4. 直到到达终点(sign为8)或者初始状态能到达的所有状态都被访问了为止。

输出方法模块:
从初始点到目标点,每一个状态都记录了前一个状态以及相应的方法sign,故从目的状态往前遍历,借用栈结构保存sign,while循环,只要该点的sign不为1(没有到达初始状态),当前点的sign入栈,移向前一位置。最后,从栈中依次弹出sign值,输出对应方法即可。

实验代码:

#include<iostream>
#include<queue>
#include<utility>
#include<stack>
using namespace std;
int sign[1001][1001]={0};		int A,B,C; 		//全局变量 
typedef pair<int,int> pairtype;
pairtype r[1001][1001];		//存储前一位置 
void fillA(int& a,int& b)
{a=A;
//	return make_pair(a,b);
}
void fillB(int& a,int& b)
{b=B;
}
void emptyA(int& a,int& b)
{a=0;
}
void emptyB(int& a,int& b)
{b=0;
}
void  AtoB(int& a,int& b)		//将A倒空或者将B倒满,总之不溢出 
{if(a<=B-b){b+=a;a=0;		//A倒空 ,!!一定要注意顺序 }else {a=a-(B-b);		 b=B;		//B倒满 }
}
void BtoA(int& a,int& b)		//A倒满或者B倒空 
{if(b<=A-a)	{a+=b;		b=0;		//B倒空 }else{b=b-(A-a);	a=A;		//A倒满 } 
} 
pairtype pourtoC(int sa,int sb)		//初始状态,返回末状态 
{queue<pairtype> q;pairtype p1(sa,sb);sign[sa][sb]=1;		//!标记!表示该节点已经访问过 if(sa==C||sb==C)return p1; q.push(p1);		//初始状态队列while(!q.empty()) 		//调用六种函数 {p1=q.front();q.pop();int x1=p1.first,x2=p1.first,x3=p1.first,x4=p1.first,x5=p1.first,x6=p1.first;		//现有状态 int y1=p1.second,y2=p1.second,y3=p1.second,y4=p1.second,y5=p1.second,y6=p1.second;//该点可能到的几种状态 fillA(x1,y1);if(!sign[x1][y1])		//该点未到达{r[x1][y1]=p1;q.push(make_pair(x1,y1));sign[x1][y1]=2;		//表示由fillA方法而来	} else{if(sign[x1][y1]==8){r[x1][y1]=p1;sign[x1][y1]=2;return make_pair(x1,y1);}}emptyA(x2,y2);if(!sign[x2][y2])		//该点未到达{r[x2][y2]=p1;q.push(make_pair(x2,y2));sign[x2][y2]=3;		//表示由fillA方法而来	} else{if(sign[x2][y2]==8)		//到达终点 {r[x2][y2]=p1;sign[x2][y2]=3;return make_pair(x2,y2);}}AtoB(x3,y3);if(!sign[x3][y3])		//该点未到达{r[x3][y3]=p1;q.push(make_pair(x3,y3));sign[x3][y3]=4;		//表示由fillA方法而来	} else{if(sign[x3][y3]==8)		//到达终点 {r[x3][y3]=p1;sign[x3][y3]=4;return make_pair(x3,y3);}	}fillB(x4,y4);if(!sign[x4][y4])		//该点未到达{r[x4][y4]=p1;q.push(make_pair(x4,y4));sign[x4][y4]=5;		//表示由fillA方法而来	} else{if(sign[x4][y4]==8){r[x4][y4]=p1;sign[x4][y4]=5;return make_pair(x4,y4);}}emptyA(x5,y5);if(!sign[x5][y5])		//该点未到达{r[x5][y5]=p1;q.push(make_pair(x5,y5));sign[x5][y5]=6;		//表示由fillA方法而来	} else{if(sign[x5][y5]==8)		//到达终点 {r[x5][y5]=p1;sign[x5][y5]=6;return make_pair(x5,y5);}}BtoA(x6,y6);if(!sign[x6][y6])		//该点未到达{r[x6][y6]=p1;q.push(make_pair(x6,y6));sign[x6][y6]=7;		//表示由fillA方法而来	} else{if(sign[x6][y6]==8)		//到达终点 {r[x6][y6]=p1;sign[x6][y6]=7;return make_pair(x6,y6);}}}return  make_pair(-1,-1); 
} void output(int tx,int ty)		//从(tx,ty)状态返回 
{stack<int> s;		//存储中间函数的栈,因为要倒着输出 int zt=sign[tx][ty];pairtype p(tx,ty);int x,y;while(zt!=1)		//没有回到初始点 {s.push(zt);x=p.first;y=p.second;p=r[x][y];		//找到前一位置 zt=sign[p.first][p.second];		//前一位置的状态 }while(!s.empty()){int zt=s.top();s.pop();switch(zt){case 2:{cout<<"fill A"<<endl;break;}case 3:{cout<<"empty A"<<endl;break;}case 4:{cout<<"pour A B"<<endl;break;}case 5:{cout<<"fill B"<<endl;break;}case 6:{cout<<"empty B"<<endl;break;}case 7:{cout<<"pour B A"<<endl;break;}}}cout<<"success"<<endl;
}
int main(void)
{while(cin>>A>>B>>C){//数组初始化 for(int i=0;i<=A;i++)for(int j=0;j<=B;j++){if(i==C||j==C)sign[i][j]=8;else sign[i][j]=0;r[i][j].first=-1;r[i][j].second=-1;}pairtype p=pourtoC(0,0);if(p.first!=-1)output(p.first,p.second);}return 0;
} 

这篇关于week2 B - Pour Water的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/494995

相关文章

吴恩达机器学习 第三课 week2 推荐算法(上)

目录 01 学习目标 02 推荐算法 2.1 定义       2.2 应用 2.3 算法 03 协同过滤推荐算法 04 电影推荐系统 4.1 问题描述 4.2 算法实现 05 总结 01 学习目标      (1)了解推荐算法      (2)掌握协同过滤推荐算法(Collaborative Filtering Recommender Algorithm)原理

Container With Most Water问题及解法

问题描述: Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Fi

【LeetCode最详尽解答】42-接雨水 Trapping-Rain-Water

欢迎收藏Star我的Machine Learning Blog:https://github.com/purepisces/Wenqing-Machine_Learning_Blog。如果收藏star, 有问题可以随时与我交流, 谢谢大家! 链接: 42-接雨水 直觉 通过可视化图形来解决这个问题会更容易理解和解决。 给定输入: height = [0,1,0,2,1,0,1,3,2,1

TOJ 4369 ZOJ 3632 Watermelon Full of Water / 线段树优化DP

Watermelon Full of Water 时间限制(普通/Java):3000MS/9000MS     运行内存限制:65536KByte 描述 Watermelon is very popular in the hot summer. Students in ZJU-ICPC Team also love watermelon very much and they

Oceanis URP Pro Water Framework(海洋水面特效插件)

Oceanis URP Pro是ARTnGame生产的URP新供水系统。该系统由URP从头开始制作,以获得最大的视觉质量。 重要: 请注意,这是Oceanis URP Pro的第一个版本,因此将根据用户反馈进行额外开发以达到完美,并将是第一个测试版,如有任何问题和建议,请在ARTnGAME Discord频道留言。 该系统将处于测试阶段一段时间,直到所有功能都投入使用并经过更广泛的测试。 重要

leetcode-42. Trapping Rain Water

leetcode-42. Trapping Rain Water 题目: Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining. For examp

hdu 4974 A simple water problem(水题)

题目链接:hdu 4974 A simple water problem 题目大意:n个人进行选秀,有一个人做裁判,每次有两人进行对决,裁判可以选择为两人打分,可以同时加上1分,或者单独为一个人加分,或者都不加。给出最后的比分情况,问说最少要比多少次才能获得现在的得分状态。 解题思路:贪心,即使每次都为两人加分的情况下需要的次数(得分总和除2),注意如果答案小于其中某人的单次得分的话说明

zoj 3913 Bob wants to pour water(二分)

题目链接:zoj 3913 Bob wants to pour water 解题思路 二分高度,判断容量。 代码 #include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;const int maxn = 1e5 + 5;const double eps =

Leetcode 042 Trapping Rain Water(高效)

题目连接:Leetcode 042 Trapping Rain Water 解题思路:从左向右遍历一遍,保存每个位置往左的最高值。再从右往左遍历一遍,保存每个位置往右的最高值。最后遍历一遍数组,取左右最高值中较小的一个,减去当前值,即为这个位置增加的量。 class Solution {public:int trap(vector<int>& height) {int n = height.s

红外超声波雷达测距(water)

文章目录 一 RS-232二 RS485三 Modbus四 stm32多路超声波测距4.1 设计方案4.2 代码 参考资料总结 实验要求 一. 采用stm32F103和HC-SR04超声波模块, 使用标准库或HAL库+ 定时器中断,完成1或2路的超声波障碍物测距功能。 1)测试数据包含噪声,程序需要进行滤波处理;将测距数值通过串口上传到上位机串口助手; 2)根据障碍物距离远近,控