题目链接:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=110&page=show_problem&problem=1544
类型: 隐式图搜索
原题:
There are three jugs with a volume of a, b and c liters. (a, b, and c are positive integers not greater than 200). The first and the second jug are initially empty, while the third
is completely filled with water. It is allowed to pour water from one jug into another until either the first one is empty or the second one is full. This operation can be performed zero, one or more times.
You are to write a program that computes the least total amount of water that needs to be poured; so that at least one of the jugs contains exactly d liters of water (d is a positive integer not greater than 200). If it is not possible to measure d liters
this way your program should find a smaller amount of water d' < d which is closest to d and for which d' liters could be produced. When d' is found, your program should compute the least total amount of poured water needed to produce d' liters in at least
one of the jugs.
Input
The first line of input contains the number of test cases. In the next T lines, T test cases follow. Each test case is given in one line of input containing four space separated integers - a, b, c and d.
Output
The output consists of two integers separated by a single space. The first integer equals the least total amount (the sum of all waters you pour from one jug to another) of poured water. The second integer equals d, if d liters of water could be produced
by such transformations, or equals the closest smaller value d' that your program has found.
样例输入:
2
2 3 4 2
96 97 199 62
样例输出:
2 2
9859 62
题目大意:
有三个杯子它们的容量分别是a,b,c, 并且初始状态下第一个和第二个是空的, 第三个杯子是满水的。可以把一个杯子的水倒入另一个杯子,当然,当被倒的杯子满了或者倒的杯子水完了,就不能继续倒了。
你的任务是写一个程序计算出用最少的倒水量,使得其中一个杯子里有d升水。如果不能倒出d升水的话,那么找到一个d' < d ,使得d'
最接近d。
分析与总结:
因为共有3个水杯, 根据每一杯的水量v1,v2,v3, 可以得到一个状态state(v1,v2,v3);
为了方便进行dfs搜索的状态转移,可以用两个三维数组volume[3], state[3]分别表示三个杯子的容量和状态。然后会有倒水的动作,可以从第1个杯子倒入第2,3个,从第2个倒入第1,3个等等……所以用两个for循环,可以遍历出所有的倒水方案。
然后注意一些不能倒水的条件,比如要倒的杯子是空的,目标杯子是满的,则不进行倒水的动作。
网上解题报告的方法: 用bfs做
// dfs,隐式图搜索
// Time: 0.072 s (UVA)
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int d, volume[3], state[3], minVolume, d1;
bool flag, vis[205][205][205];
void search(int tot){
// 更新结果的状态,有不少地方需要注意
for(int i=0; i<3; ++i){
if(state[i] && state[i] == d){
d1 = d;
if(!flag) minVolume = tot; // 第一次发现等于d,那么直接把当前总量tot赋给minVolume
else if(tot<minVolume) minVolume = tot; // 以后有其他情况等于d的,只有tot小于minVolume才更新
flag=true; // 标志为已经找到等于d的了
}
else if(!flag && state[i] && state[i] < d){// 注意: !flag表示只有没有找到等于d的情况,才会执行下面这些语句
if(d-state[i]<d1){
d1 = d-state[i];
minVolume = tot;
}
else if(d-state[i]==d1 && tot<minVolume)
minVolume = tot;
}
}
for(int i=0; i<3; ++i){
for(int j=0; j<3; ++j)if(i!=j && state[i] && state[j]!=volume[j] ){
int add;
int tmp_i = state[i], tmp_j = state[j]; // 备份,回溯后要恢复
if(state[i] >= volume[j]-state[j]){ // 如果倒的水大于等于被倒杯子剩余容量,那么将被倒满
add = volume[j]-state[j];
state[i] -= add;
state[j] = volume[j];
}
else{ // 否则,全部倒光到目标杯子里
state[j] += state[i];
add = state[i];
state[i] = 0;
}
if(!vis[state[0]][state[1]][state[2]]){
vis[state[0]][state[1]][state[2]] = true;
search(tot+add);
vis[state[0]][state[1]][state[2]] = false; // 回溯,恢复状态
}
state[i] = tmp_i; // 回溯,恢复状态
state[j] = tmp_j;
}
}
}
int main(){
int T;
scanf("%d", &T);
while(T--){
scanf("%d%d%d%d",&volume[0],&volume[1],&volume[2],&d);
state[0]=0, state[1]=0, state[2]=volume[2];
memset(vis, 0, sizeof(vis));
vis[0][0][volume[2]] = true;
flag = false;
minVolume = d1 = 1000000;
search(0);
if(flag) printf("%d %d\n", minVolume, d1);
else printf("%d %d\n", minVolume, d-d1);
}
return 0;
}
—— 生命的意义,在于赋予它意义。
分享到:
相关推荐
基于MATLAB实现微分方程有限元离散+隐式梯度计算+SQP求解优化问题源码(常微分系统).zip基于MATLAB实现微分方程有限元离散+隐式梯度计算+SQP求解优化问题源码(常微分系统).zip基于MATLAB实现微分方程有限元离散+隐式...
javaScript基础入门篇-运算符+类型转换(隐式转换和强制转换)+流程控制语句(循环遍历和if判断),此文件typora和Visual Studio Code可以打开
- **CTRL+SHIFT+-**:返回上一步。 - **CTRL+F4**:关闭当前文档。 - **CTRL+PAGEDOWN**:移动到下一个文档。 - **CTRL+PAGEUP**:移动到上一个文档。 - **CTRL+F6**:移动到下一个文档。 - **CTRL+TAB**:移动到下...
标题中的“行业文档-设计装置-多功能隐式台灯电风扇”揭示了这个压缩包包含的是关于一个创新设计的产品——多功能隐式台灯电风扇的相关资料。这种装置结合了台灯和电风扇的功能,旨在提供一种更为实用和节省空间的...
LS-DYNA是一款广泛应用于工程领域中的高度非线性有限元分析软件,其具备显示和隐式两种求解方法,用于模拟不同类型的物理现象。标题中的“显示—隐式求解步骤”说明了本文将着重介绍如何在LS-DYNA中操作显示求解和...
在实际应用中,隐式条码技术还需要考虑兼容性和标准问题。与传统的显式条码相比,隐式条码的读取设备可能更为专业,因此需要确保在不同场景下都能顺利读取。同时,制定和遵循统一的标准是确保不同系统间互操作性的...
在IT领域,特别是数据分析和机器学习的分支,"基于稀疏隐式特征表达的有监督在线话题模型学习方法"是一个重要的研究方向。这个主题涉及到如何有效地处理大量数据,特别是那些包含隐含信息的数据,比如用户行为、设备...
在这个主题中,我们关注的是FTP与SSL(Secure Sockets Layer)和TSL(Transport Layer Security)的安全结合,以及如何进行隐式调用。SSL和TSL都是为网络通信提供加密处理和身份验证的安全协议,它们确保了数据在...
oauth-ng, 针对 OAuth 2.0隐式流的AngularJS指令 面向 OAuth 2.0 的 AngularJS指令 用于 OAuth 2.0隐式流处理器的AngularJS指令。文档 fork 在github上发送 repo 请求并发送带有主题分支的请求请求。 不要忘了为你的...
为了求解三维欧拉方程,对隐式时间离散格式间断有限元方法进行了研究。根据间断Galerkin有限元方法思想,构造内迭代SOR-LU-SGS隐式时间离散格式,结合当地时间步长技术、多重网格方法,实现了三维流场的计算。数值...
《图像处理源码-nglod-神经几何细节水平:隐式3D曲面的实时渲染》 在当前的计算机图形学领域,图像处理和人工智能技术的发展正在不断推动着3D渲染技术的进步。本项目的核心在于“nglod”,这是一种创新的神经网络...
0105_极智AI_解读TensorRT显式batch和隐式batch-个人笔记
本文将详细探讨基于3步4阶隐式泰勒级数法的电磁暂态数值计算方法,这是一种高效且精确的计算技术。 首先,理解电磁暂态过程的含义至关重要。电磁暂态是指在电力系统中的快速变化现象,通常涉及到电压、电流的瞬间...
工作过程中会遇到比较多关于隐式转换的案例,隐式转换除了会导致慢查询,还会导致数据不准。本文通过几个生产中遇到的案例来。 基础知识 关于比较运算的原则,MySQL官方文档的描述: ...
CAST 函数 在之前的文章中,我们提到过CAST...+----------------------------+ | CAST('2017-12-14' AS DATE) | +----------------------------+ | 2017-12-14 | +----------------------------+ 1 row in set (0.00 s
动态优化是一种重要的计算技术,主要用于解决在满足一系列约束条件下的最优化问题,特别是在物理、工程、经济等领域中的动态过程。本程序包专为常微分系统(Continuous-Time Ordinary Differential Equations, ODEs...
描述android 多线程下载文件的详细步骤+断点续传 多线程下载步骤分析 1、获取服务器文件大小 conn.getContentLength(); 2、在客户端创建一个和服务大小一模一样的文件(目的:提前申请好空间) ...
这种方法的核心在于利用泰勒级数展开,将复杂的非线性微分方程组转化为一组线性代数问题,然后通过迭代求解。具体来说,它分为以下三个步骤: 1. **初始化**:首先,使用已知的初始条件和时间步长来确定系统状态的...
由于异端基于Doom v1.2,因此将其隐式设置为0 。 将“状态栏和菜单外观”选项设置为“未调整”将对异端无效(默认为“缩放格式”)。 对于异端禁用了“应用多重采样”自动映射选项。 自动地图部