二分算法题目训练(一)——Shell Pyramid详解
HDU2446——Shell Pyramid 详解
- Shell Pyramid
题目描述(Google 翻译的)
在17世纪,由于雷鸣般的喧嚣,浓烟和炽热的火焰,海上的战斗与现代战争一样。但那时,大炮非常简单。它就像一个铁缸,其后端密封,前端打开。它的后端有一个小孔,用来安装保险丝。战舰上的大炮被放在有四个轮子的小型车辆上,炮弹是铁球,里面装着火药。当时,据说有一位聪明的船长,他也是一位数学家的业余爱好者。他喜欢把他遇到的所有东西都连接到数学上。在每次战斗之前,他经常命令士兵将炮弹放在甲板上并使这些炮弹形成炮弹金字塔。
现在让我们假设一个壳金字塔有四层,每层都会有一系列序数。它们如下图所示:
在该图中,它们分别是从左到右的第一层,第二层,第三层和第四层。
在第一层中,只有1个壳,其序数为1.在第二层中,有3个壳,它们的序数为1,2和3.在第三层中,有6个壳,它们的序数分别为1,2,3,4,5和6.在第四层中,有10个壳,它们的序数在上图中显示。
整个贝壳金字塔也有序列号。例如,第二层中第三个外壳的序列号为4,第三层中第五个外壳的序列号为9,第四层中第九个外壳的序列号为19。
还有一个相互关联的问题:如果给出一个序列号s,那么我们可以计算出第s个shell是在什么层,什么行和什么列。假设层数是i,行数是j而列数是k,因此,如果s = 19,则i = 4,j = 4并且k = 3。
现在让我们继续讲述船长的故事。
一场战斗即将开始。船长给每个大炮分配了相同数量的炮弹。炮弹堆放在甲板上,由炮弹形成相同的炮弹金字塔。当敌人的战舰靠近时,船长命令同时开火。然后听到了雷鸣般的声音。船长仔细听了,然后他就知道有多少炮弹被使用了,剩下多少炮弹了。在战斗结束时,船长赢了。在休息期间,他向下属询问了一个问题:对于壳金字塔,如果给出序列号s,你如何计算层数i,行号j和列号k?
- 输入
首先输入一个数字n,再进行n个案例。对于每种情况,都有一个足够大的壳金字塔,给出一个整数,这个整数是序列号s(s <2 ^ 63)。有几个测试用例。输入由文件末尾终止。 - 输出
对于每种情况,输出相应的层编号i,行编号j和列编号k。 - 样例输入
2
19
75822050528572544 - 样例输出
4 4 3
769099 111570 11179 - 思路分析
- 首先通过二分先确定给出的数字是哪个金字塔,要找到是哪个金字塔,就需要知道给定序号代表的意思,序号是宏观的炮弹下标,因此它必然代表之前已经出现的所有炮弹,要找到它属于第几个金字塔,就需要一个数组来存储对于金字塔序号 i,它和它之前所有的金字塔会产生多少炮弹。
- 再通过二分确定是属于这个金字塔的哪一层。要找到它是哪一层,就需要知道这个金字塔有多少个炮弹,因此还需要一个数组来存储对于金字塔序号 i,它自己会产生多少炮弹。
- 设计思路
- 对于第 i 个金字塔,它所包含的炮弹数都是第 i-1 个金字塔所包含的炮弹数加上 i,比如第二个金字塔有 3 个炮弹,那么第三个就有 3+3 个炮弹,因此得到非递减序列 a[i] = a[i-1] + i
- 对于第 i 个金字塔,所有的炮弹数目为 i-1 个金字塔所包含炮弹数目与自己含有炮弹之和,因此得到非递减序列 sum[i] = sum[i-1] + a[i]
- 接下来只需要两次二分找出结果,找到金字塔序号 p 后,减去sum[p-1],就会得到所在金字塔中第多少个炮弹,找到行号 row 后,减去a[row-1],就是列号。
#include <iostream>
#include <cstdio>
#include<cmath> #define Maxn 1000000 using namespace std; typedef long long int LL; LL a[Maxn];
LL sum[Maxn]; LL find_index(LL *array,LL size,LL key); int main()
{
int i;
a[] = ;
for(i=; i<Maxn; i++)
{
a[i] = a[i-]+i;
}
sum[] = ;
for(i=; i<Maxn; i++)
{
sum[i] = sum[i-]+a[i];
}
int t;
scanf("%d",&t);
while(t--)
{
LL num;
cin >> num;
LL p = find_index(sum,Maxn,num);
num -= sum[p-];
LL row = find_index(a,Maxn,num);
LL col = num-a[row-];
cout<<p<<" "<<row<<" "<<col<<endl;
}
return ;
}
LL find_index(LL *array,LL size,LL key)
{
int first = , last = size-;
int middle, pos=; while(first < last)
{
middle = (first+last)/;
if(array[middle] < key)
{
first = middle + ;
pos = first;
}
else
{
last = middle;
pos = last;
}
}
return pos;
}
- 对于非递减序列,可以使用 STL 中的 lower_bound()
#include <iostream>
#include <cstdio>
#include<cmath> #define Maxn 1000000 using namespace std; typedef long long int LL; LL a[Maxn];
LL sum[Maxn]; int main()
{
int i;
a[] = ;
for(i=;i<Maxn;i++)
{
a[i] = a[i-]+i;
}
sum[] = ;
for(i=;i<Maxn;i++)
{
sum[i] = sum[i-]+a[i];
}
int t;
scanf("%d",&t);
while(t--)
{
LL num;
cin >> num;
LL p = lower_bound(sum,sum+Maxn,num)-sum;
num -= sum[p-];
LL row = lower_bound(a,a+Maxn,num)-a;
LL col = num-a[row-];
cout<<p<<" "<<row<<" "<<col<<endl;
}
return ;
}
二分算法题目训练(一)——Shell Pyramid详解的更多相关文章
- 二分算法题目训练(四)——Robin Hood详解
codeforces672D——Robin Hood详解 Robin Hood 问题描述(google翻译) 我们都知道罗宾汉令人印象深刻的故事.罗宾汉利用他的射箭技巧和他的智慧从富人那里偷钱,然后把 ...
- 二分算法题目训练(三)——Anton and Making Potions详解
codeforces734C——Anton and Making Potions详解 Anton and Making Potions 题目描述(google翻译) 安东正在玩一个非常有趣的电脑游戏, ...
- 二分算法题目训练(二)——Exams详解
CodeForces732D——Exams 详解 Exam 题目描述(google翻译) Vasiliy的考试期限将持续n天.他必须通过m门科目的考试.受试者编号为1至m. 大约每天我们都知道当天可以 ...
- adb shell 命令详解,android
http://www.miui.com/article-275-1.html http://noobjava.iteye.com/blog/1914348 adb shell 命令详解,android ...
- [转]EM算法(Expectation Maximization Algorithm)详解
https://blog.csdn.net/zhihua_oba/article/details/73776553 EM算法(Expectation Maximization Algorithm)详解 ...
- 【Devops】【docker】【CI/CD】关于jenkins构建成功后一步,执行的shell命令详解+jenkins容器运行宿主机shell命令的实现方法
1.展示这段shell命令 +详解 #================================================================================= ...
- Linux主要shell命令详解(上)
[摘自网络] kill -9 -1即实现用kill命令退出系统 Linux主要shell命令详解 [上篇] shell是用户和Linux操作系统之间的接口.Linux中有多种shell,其中缺省使用的 ...
- adb shell 命令详解,android, adb logcat
http://www.miui.com/article-275-1.html http://noobjava.iteye.com/blog/1914348 adb shell 命令详解,android ...
- linux shell `符号详解
linux shell `符号详解 <pre>[root@iZ23uewresmZ arjianghu]# echo `ls`asss.html common guaji.php imag ...
随机推荐
- C#进阶系列——WebApi异常处理解决方案
阅读目录 一.使用异常筛选器捕获所有异常 二.HttpResponseException自定义异常信息 三.返回HttpError 四.总结 正文 为什么说是实践?因为在http://www.asp. ...
- dB分贝计算
1. 定义 dB-表征相对值的大小的单位,即两个电.声功率之比或者电流.电压.音量之比,是一种测相对大小的单位. 1.1 电.声功率之比——10lg(x/y) x.y分别表示两个欲比较的功率值. 例如 ...
- nginx 禁止浏览器缓存
如果我们使用Nginx作为静态资源服务器,那么可以使用expires进行缓存控制. location /{ expires 1s; } 如果Get页面未做任何修改,服务器就是对客户端返回304 Not ...
- POJ1861(Network)-Kruskal
题目在这 Sample Input 4 6 1 2 1 1 3 1 1 4 2 2 3 1 3 4 1 2 4 1 Sample Output 1 4 1 2 1 3 2 3 3 4 题目意思:4个点 ...
- STM8 uart1
举例 int main() { UART1_DeInit(); //波特率9600,数据位8,停止位1,校验位无,非同步模式,发送接收使能 UART1_Init(9600, UART1_WORDLEN ...
- Mysql 中的SSL 连接
Mysql 中的SSL 连接 以下来自网络参考和自己测试整理,没有查找相关资料.若有错误之处,欢迎指正. 当前的Mysql 客户端版本基本都不太能支持 caching_sha2_password 认证 ...
- Gitlab CI/CD任务一直处于pending
在注册Runner时候这里输入了tag,这里指的是runner的标签,可以设置多个 ,分别用 ,号分割 .gitlab-ci.yml文件中 stages: - pull - package - bu ...
- request-html模块 (上)
requests-html模块 官方网站 Github网址 请求数据 from requests_html import HTMLSession session = HTMLSession() req ...
- Django 中使用权限认证
权限认证 权限概念 """ 在实际开发中,项目中都有后台运营站点,运营站点里面会存在多个管理员, 那么不同的管理员会具备不同的任务和能力,那么要实现这样的管理员功能,那么 ...
- Windows——系统盘重置密码
一.制作好系统启动U盘 软碟通自己制作即可 二.这进入到安装前界面按Shift+F10调出命令提示符 三.输入regedit后按回车进入注册表编辑器 四. 左键单击选中HKEY_LOCAL_MACHI ...