Uva 12627 Erratic Expansion(不稳定膨胀)
题目链接 : Erratic Expansion
大致题意:
开始时有一个红气球,每过一段时间,气球会膨胀,
一个红气球膨胀成三个红气球,一个蓝气球膨胀成四个蓝气球(如图)
题目输入正整数n表示n组数据,每组数据有三个数,k,a,b,要返回第k个时刻的a到b的红气球总数。
思路:
通过图像不难发现,把第k个时刻的图均分为4个正方形,那么左上,右上,左下三个正方形都和k-1时刻的正方形一样,右下则全是蓝色气球,不用考虑。通过这样的分治思想,我们可以递归地得到任意k时刻的正方形前m行的红气球总数,那么f(k, b) - f(k, a-1)就是我们要得到的答案。按照这样的思路,不难写出如下代码 :
#include <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;/* 用来求时刻k时,前h行的红气球数量的函数 */
long long redNum(long k, long h){//递归出口if(h <= 0) return 0;if(k == 0 && h == 1) return 1;//算出此时正方形的行数的一半(k时刻行数是2^k,一半是2^(k-1))long long mid = pow(2, k-1);//如果行数超过一半,分上下两部分看,上半部分是两个k-1时刻的正方形左右拼接在一起//下半部分左边也是一个k-1时刻的正方形,取前h-mid行。右边全是蓝气球,和为0if(h > mid) return 2 * redNum(k-1, mid) + redNum(k-1, h-mid);//如果行数没超过一半,那么只看上半部分,发现上半部分可以等效为k-1时刻的正方形两个左右拼接在一起,两个正方形都取前h行else return 2 * redNum(k-1, h);
}
int main(){int n;cin >> n;for(int i=1; i<=n; i++){long k, a, b;cin >> k >> a >> b;printf("Case %d: ",i);cout << redNum(k, b) - redNum(k, a-1) << '\n';}
}
然后,就超时了orz。
为什么会超时呢,主要是因为 2 * redNum(k-1, mid) 有大量的重复计算,而 2 * redNum(k-1, mid) 表示第k-1时刻的整个正方形的红气球数,实际上它等于3^(k-1)(这个也是我自己手算找规律的时候发现的),然后,只需要把这一句改了,就能ac了。
以下是已ac的代码:
#include <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;/* 用来求时刻k时,前h行的红气球数量的函数 */
long long redNum(long k, long h){//递归出口if(h <= 0) return 0;if(k == 0 && h == 1) return 1;//算出此时正方形的行数的一半(k时刻行数是2^k,一半是2^(k-1))long long mid = pow(2, k-1);//如果行数超过一半,分上下两部分看,上半部分是两个k-1时刻的正方形左右拼接在一起//所以上半部分是2 * redNum(k-1, mid),经过计算可以发现它等于2 * (long long) pow(3, k-1)//下半部分左边也是一个k-1时刻的正方形,取前h-mid行。右边全是蓝气球,和为0//所以下半部分是2 * redNum(k-1, h-mid)if(h > mid) return 2 * (long long)pow(3, k-1) + redNum(k-1, h-mid);//如果行数没超过一半,那么只看上半部分,发现上半部分可以等效为k-1时刻的正方形两个左右拼接在一起,两个正方形都取前h行else return 2 * redNum(k-1, h);
}
int main(){int n;cin >> n;for(int i=1; i<=n; i++){long k, a, b;cin >> k >> a >> b;printf("Case %d: ",i);cout << redNum(k, b) - redNum(k, a-1) << '\n';}
}
Uva 12627 Erratic Expansion(不稳定膨胀)相关推荐
- UVa 12627 Erratic Expansion - 分治
因为不好复制题目,就出给出链接吧: Vjudge传送门[here] UVa传送门[here] 请仔细看原题上的那幅图,你会发现,在时间t(t > 0),当前的气球构成的一幅图,它是由三个时间为( ...
- UVA - 12627 - Erratic Expansion(找规律递归)
递归找规律即可,用前b行减去前a-1行的红气球个数求解,细节见代码 #include<cstdio> #include<cstring> #include<cstdlib ...
- UVa 12627 - Erratic Expansion
链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- uva 12627——Erratic Expansion
题意:一开始有1个红气球,每小时一个红气球都会变成3个红气球和1个蓝气球,1个蓝气球会变成4个蓝气球,问k个小时后a行到b行的红气球的数量. 思路:递推.a为偶数时,计算a+1到b以及a本行的红气球数 ...
- Uva 12627 Erratic Expansion
这道题大体意思是利用一种递归规则生成不同的气球,问在某两行之间有多少个红气球. 我拿到这个题,一开始想的是递归求解,但在如何递归求解的思路上我的方法是错误的.在研读了例题上给出的提示后豁然开朗(顺便吐 ...
- UVA 12627 Erratic Expansion
题目大致意思为 告诉你一个红球为0时状态,已知一个红球每过一个时间会变为文档所示图中的3红1蓝,而蓝球每过一个时间则会变为4个蓝球.问在某一时刻,h1与h2之间的红球有几个. RT,这一题刚看到的时候 ...
- UVA - 12627 Erratic Expansion : 递归
题目点此跳转 思路 题目意思是(书上原话)一开始有一个红气球.每小时后,一个红气球会变成3个红气球和一个蓝气球,一个蓝气球会变成4个蓝气球,如图所示分别是经过0, 1, 2, 3小时后的情况.经过k ...
- Uva - 12627 - Erratic Expansion
找到递推公式,题目就引刃而解了.数学公式博文没办法写,就写在了word上,切过来了: 用 f 或者 g 都能求出,我两个方法都试了,结果用 g 要比 f 快了近一倍,原本以为 f 会快些,可能是因为往 ...
- uva 12627 Erratic Expansion
原题: Piotr found a magical box in heaven. Its magic power is that if you place any red balloon inside ...
最新文章
- Wireshark筛选常用命令
- CC2541对AT24CXX系列存储器的支持
- zabbix的安装与部署(proxy、睿象云)
- VS 调用外部DLL时提示“无法嵌入互操作类型”
- framebuffer驱动详解2——framebuffer驱动框架分析
- Hadoop学习笔记—10.Shuffle过程那点事儿
- django-xadmin使用之更改菜单url
- 金三银四大厂面经总结,java模块化打包
- UVA12169模运算
- 1694件AI事件大盘点!2020年12月,哪些让你记忆深刻
- 如何查看java安装成功_如何查看java是否安装成功
- 极光尔沃:太空3D打印机首次亮相 航天领域应用潜力巨大
- ui界面设计工具有哪些
- Youtube羽翼丰满 欲摆脱运营商自建移动版网站
- 【分隔结构】动宾分离
- 小程序导航栏透明,精准设置小程序自定义标题的高度和定位
- be going to用法口诀
- c语言判断一个数是否为偶数源代码,c语言判断一个数是否为偶数
- 云计算零基础(2)配置yum仓库
- 超级计算机的应用例子简单介绍,应用程序ZEUS-3D的简短介绍
热门文章
- [转载] iframe嵌入网页的用法
- 使用01字典树解决最大异或问题
- 南昌大学2014~2015学年第二学期数据结构期末考试试卷试题解析
- PMP证书的必要性、培训机构选择以及其他相关问题整理
- 配置nginx的地址和路径的代理
- Commons Email-电子邮件发送
- Python+Vue计算机毕业设计框架的综合性电商6si2i(程序+LW+源码+部署)
- 如何正确获取 wifi mac地址
- 2022-2028全球与中国纳米沉淀碳酸钙市场现状及未来发展趋势
- 【毕业设计】16-基于单片机的酒精浓度监测系统设计(原理图+仿真+实物图+论文+答辩PPT)