hdu4803 Poor Warehouse Keeper
2015-08-18 16:07
337 查看
给定两个数字显示板A, B和两个按钮,按下按钮使得其对应数字显示增加1。
另,B显示板只显示其实际值的整数部分。两显示器对应的实际值有一个比值p。
按下A板上的按钮, A板上显示的数增加1到a + 1, p不变,B板上的数字更新为(int)(b * (a + 1) / a)。
按下B板上的按钮,A板上上显示的数值不变,B 板加1 到b + 1,p更新为(b + 1) / a。
给定目标状态(a1, b1),问至少经过多少次按下按钮可从初始状态(1, 1)到达该状态。
若不可达输出-1。
显然按下A板按钮使得B板数值成比例增加,比值为p,按下B板数值使得比例增加。
比例增加过程不可逆,状态不可达当且仅当a1 < b1。
首先从A板数组从1增加到a1至少需要a1 - 1次操作,这与B板的状态无关。
而A板的数值变化会引起B板成倍增加,考虑到f(i) = (i + 1) / i是严格递减函数。
直观上我们有应该尽可能把按A板的操作提前,这样B板上的数值就会尽快接近目标值。
注意到比值p<(b + 1) / a,我们尽可能向该值靠近,从1开始。
然后随着A板数值增大,逐步逼近该值,记录下B板的操作次数,即可解决此题。
浮点数执行近似运算,导致误差,本题用分数表示有理数(比值)。
acm.hdu.edu.cn/showproblem.php?pid=4803
View Code
另,B显示板只显示其实际值的整数部分。两显示器对应的实际值有一个比值p。
按下A板上的按钮, A板上显示的数增加1到a + 1, p不变,B板上的数字更新为(int)(b * (a + 1) / a)。
按下B板上的按钮,A板上上显示的数值不变,B 板加1 到b + 1,p更新为(b + 1) / a。
给定目标状态(a1, b1),问至少经过多少次按下按钮可从初始状态(1, 1)到达该状态。
若不可达输出-1。
显然按下A板按钮使得B板数值成比例增加,比值为p,按下B板数值使得比例增加。
比例增加过程不可逆,状态不可达当且仅当a1 < b1。
首先从A板数组从1增加到a1至少需要a1 - 1次操作,这与B板的状态无关。
而A板的数值变化会引起B板成倍增加,考虑到f(i) = (i + 1) / i是严格递减函数。
直观上我们有应该尽可能把按A板的操作提前,这样B板上的数值就会尽快接近目标值。
注意到比值p<(b + 1) / a,我们尽可能向该值靠近,从1开始。
然后随着A板数值增大,逐步逼近该值,记录下B板的操作次数,即可解决此题。
浮点数执行近似运算,导致误差,本题用分数表示有理数(比值)。
acm.hdu.edu.cn/showproblem.php?pid=4803
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef __int64 LL; LL a, b; LL gcd(LL a, LL b){ if(!b) return a; return gcd(b, a % b); } void solve(){ if(b < a){ printf("-1\n"); return; } LL lhs = 1, rhs = 1; //rhs :: denominator //lhs :: numerator LL cnt = a - 1; //operations required for A for(int i = 1; i <= a; i++){ LL f = (b + 1) * i * lhs - a * rhs, g = a * lhs; LL k = (f % g == 0 ? f / g - 1 : f / g); cnt += k; //extra operations required for B rhs += k * lhs; LL GCD = gcd((i + 1) * rhs, i * lhs); rhs = rhs * (i + 1) / GCD; lhs = lhs * i /GCD; } printf("%I64d\n", cnt); } int main(){ while(~scanf("%I64d%I64d", &a, &b)){ solve(); } return 0; }
View Code
相关文章推荐
- WITH AS 用法
- linux shell中判断文件的参数说明
- java中StringBuilder、StringBuffer、String类之间的关系
- php 压缩服务器上的文件为zip 和下载zip文件
- tifuzi问题归纳
- Ubuntu12.04 Tomcat环境变量设置并开机启动
- 解决没有点击Spinner,还会执行setOnItemSelectedListener监听
- GPIO模拟I2C程序实现
- java定时器的写法
- 从输入 URL 到浏览器接收的过程中发生了什么事情?
- hdu 1222 狼和兔子
- 如何记录系统(oa)的操作日志 ?
- 【LeetCode】235. Lowest Common Ancestor of a Binary Search Tree
- STM32F4xx FPU的设置(转载)
- [原创]计算几何个人模板
- openCV—Python(10)—— 图像阈值化处理
- MyEclipse 快捷键
- 操作系统原理——处理器调度
- C++中extern关键字使用(转)
- 系统内置委托:Func/Action