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,它自己会产生多少炮弹。
  • 设计思路
    1. 对于第 i 个金字塔,它所包含的炮弹数都是第 i-1 个金字塔所包含的炮弹数加上 i,比如第二个金字塔有 3 个炮弹,那么第三个就有 3+3 个炮弹,因此得到非递减序列 a[i] = a[i-1] + i
    2. 对于第 i 个金字塔,所有的炮弹数目为 i-1 个金字塔所包含炮弹数目与自己含有炮弹之和,因此得到非递减序列 sum[i] = sum[i-1] + a[i]
    3. 接下来只需要两次二分找出结果,找到金字塔序号 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详解的更多相关文章

  1. 二分算法题目训练(四)——Robin Hood详解

    codeforces672D——Robin Hood详解 Robin Hood 问题描述(google翻译) 我们都知道罗宾汉令人印象深刻的故事.罗宾汉利用他的射箭技巧和他的智慧从富人那里偷钱,然后把 ...

  2. 二分算法题目训练(三)——Anton and Making Potions详解

    codeforces734C——Anton and Making Potions详解 Anton and Making Potions 题目描述(google翻译) 安东正在玩一个非常有趣的电脑游戏, ...

  3. 二分算法题目训练(二)——Exams详解

    CodeForces732D——Exams 详解 Exam 题目描述(google翻译) Vasiliy的考试期限将持续n天.他必须通过m门科目的考试.受试者编号为1至m. 大约每天我们都知道当天可以 ...

  4. adb shell 命令详解,android

    http://www.miui.com/article-275-1.html http://noobjava.iteye.com/blog/1914348 adb shell 命令详解,android ...

  5. [转]EM算法(Expectation Maximization Algorithm)详解

    https://blog.csdn.net/zhihua_oba/article/details/73776553 EM算法(Expectation Maximization Algorithm)详解 ...

  6. 【Devops】【docker】【CI/CD】关于jenkins构建成功后一步,执行的shell命令详解+jenkins容器运行宿主机shell命令的实现方法

    1.展示这段shell命令 +详解 #================================================================================= ...

  7. Linux主要shell命令详解(上)

    [摘自网络] kill -9 -1即实现用kill命令退出系统 Linux主要shell命令详解 [上篇] shell是用户和Linux操作系统之间的接口.Linux中有多种shell,其中缺省使用的 ...

  8. adb shell 命令详解,android, adb logcat

    http://www.miui.com/article-275-1.html http://noobjava.iteye.com/blog/1914348 adb shell 命令详解,android ...

  9. linux shell `符号详解

    linux shell `符号详解 <pre>[root@iZ23uewresmZ arjianghu]# echo `ls`asss.html common guaji.php imag ...

随机推荐

  1. C#进阶系列——WebApi异常处理解决方案

    阅读目录 一.使用异常筛选器捕获所有异常 二.HttpResponseException自定义异常信息 三.返回HttpError 四.总结 正文 为什么说是实践?因为在http://www.asp. ...

  2. dB分贝计算

    1. 定义 dB-表征相对值的大小的单位,即两个电.声功率之比或者电流.电压.音量之比,是一种测相对大小的单位. 1.1 电.声功率之比——10lg(x/y) x.y分别表示两个欲比较的功率值. 例如 ...

  3. nginx 禁止浏览器缓存

    如果我们使用Nginx作为静态资源服务器,那么可以使用expires进行缓存控制. location /{ expires 1s; } 如果Get页面未做任何修改,服务器就是对客户端返回304 Not ...

  4. 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个点 ...

  5. STM8 uart1

    举例 int main() { UART1_DeInit(); //波特率9600,数据位8,停止位1,校验位无,非同步模式,发送接收使能 UART1_Init(9600, UART1_WORDLEN ...

  6. Mysql 中的SSL 连接

    Mysql 中的SSL 连接 以下来自网络参考和自己测试整理,没有查找相关资料.若有错误之处,欢迎指正. 当前的Mysql 客户端版本基本都不太能支持 caching_sha2_password 认证 ...

  7. Gitlab CI/CD任务一直处于pending

    在注册Runner时候这里输入了tag,这里指的是runner的标签,可以设置多个  ,分别用 ,号分割 .gitlab-ci.yml文件中 stages: - pull - package - bu ...

  8. request-html模块 (上)

    requests-html模块 官方网站 Github网址 请求数据 from requests_html import HTMLSession session = HTMLSession() req ...

  9. Django 中使用权限认证

    权限认证 权限概念 """ 在实际开发中,项目中都有后台运营站点,运营站点里面会存在多个管理员, 那么不同的管理员会具备不同的任务和能力,那么要实现这样的管理员功能,那么 ...

  10. Windows——系统盘重置密码

    一.制作好系统启动U盘 软碟通自己制作即可 二.这进入到安装前界面按Shift+F10调出命令提示符 三.输入regedit后按回车进入注册表编辑器 四. 左键单击选中HKEY_LOCAL_MACHI ...