HDU 2446 Shell Pyramid(二分查找 数学)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2446

Problem Description

In the 17th century, with thunderous noise, dense smoke and blazing fire, battles on the sea were just the same as those in the modern times. But at that time, the cannon ,were extremely simple. It was just like an iron cylinder, with its rearward end sealed
and forward end open. There was a small hole at the rearward end of it, which was used to install the fuse. The cannons on the warships were put on small vehicles which had four wheels and the shells were iron spheres with gunpowder in them.

At that time, it was said that there was an intelligent captain, who was also a mathematician amateur. He liked to connect everything him met to mathematics. Before every battle, he often ordered the soldiers to put the shells on the deck and make those shells
to form shell pyramids.

Now let‘s suppose that a shell pyramid has four layers, and there will be a sequence of ordinal numbers in every layer. They are as the following figure:

In the figure, they are the first layer, the second layer, the third layer and the fourth layer respectively from the left to the right.

In the first layer, there is just 1 shell, and its ordinal number is 1. In the second layer, there are 3 shells, and their ordinal numbers are 1, 2, and 3. In the third layer, there are 6 shells, and their ordinal numbers are 1, 2, 3, 4, 5, and 6. In the fourth
layer, there are 10 shells, and their ordinal numbers are shown in the figure above.

There are also serial numbers for the whole shell pyramid. For example, the serial number for the third shell in the second layer is 4, the serial number for the fifth shell in the third layer is 9, and the serial number for the ninth shell in the fourth layer
is 19.

There is also a interrelated problem: If given one serial number s, then we can work out the s th shell is in what layer, what row and what column. Assume that the layer number is i, the row number is j and the column number is k, therefore, if s=19, then i=4,
j=4 and k=3.

Now let us continue to tell about the story about the captain.

A battle was going to begin. The captain allotted the same amount of shells to every cannon. The shells were piled on the deck which formed the same shell pyramids by the cannon. While the enemy warships were near, the captain ordered to fire simultaneously.
Thunderous sound then was heard. The captain listened carefully, then he knew that how many shells were used and how many were left.

At the end of the battle, the captain won. During the break, he asked his subordinate a question: For a shell pyramid, if given the serial number s, how do you calculate the layer number i, the row number j and column number k?

Input

First input a number n,repersent n cases.For each case there a shell pyramid which is big enough, a integer is given, and this integer is the serial number s(s<2^63). There are several test cases. Input is terminated by the end of file.

Output

For each case, output the corresponding layer number i, row number j and column number k.

Sample Input

2
19
75822050528572544

Sample Output

4 4 3
769099 111570 11179

Source

2008 Asia Regional Harbin

题意:

叠金字塔,最顶层数量是1,第二层数量是3,之后每一层的数量都是上面一层的数量加当前层数的值啦。一层金字塔有1个球,两层金字塔有1+3 = 4个球,三层金字塔就有1+3+6 = 10个的球。

现在给出一个编号s,问它在金字塔中的第几层,第几行,第几列。

例如19,在第四层,第四行,第三列。

PS:

首先打表出每一座金字塔的数量, 和第n座金字塔的编号(也就是前n座金字塔共有的数量);

然后先二分查找出给出的编号所在的金字塔,然后再一次二分找出给出的编号在当前金字塔的哪一行哪一列!

代码如下:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
typedef __int64 LL;

#define N 2000017
LL p[N] = {0}, sn[N] = {0};
//a每一个位置的数,b:Sn

LL findd1(LL n)
{
    LL s = 1, e = N, mid;

    while(s < e)
    {
        mid = (s+e)/2;
        if(sn[mid] < n)
            s = mid+1;
        else if(sn[mid] > n)
            e = mid-1;
        else
            return mid;
    }
    return s;
}

LL findd2(LL n, LL endd)
{
    LL s = 1, e = endd, mid;

    while(s < e)
    {
        mid = (s+e)/2;
        if(p[mid] < n)
            s = mid+1;
        else if(p[mid] > n)
            e = mid-1;
        else
            return mid;
    }
    return s;
}

int main()
{
    LL t;
    LL n;
    memset(p,0,sizeof(p));
    memset(sn,0,sizeof(sn));
    for(int i = 1; i < N; i++)//每一堆
    {
        p[i] = p[i-1]+i;
    }
    for(int i = 1; i < N; i++)//Sn
    {
        sn[i] = p[i]+sn[i-1];
    }
    /* for(int i = N-10; i < N; i++)
     {
         printf("%I64d\n",sn[i]);
     }*/
    //2^63 = 9223372036854775808
    scanf("%I64d",&t);
    while(t--)
    {
        scanf("%I64d",&n);
        LL weizhi = findd1(n);

        // printf("pos:%I64d\n",weizhi);

        if(sn[weizhi] < n)
            weizhi+=1;
        LL tt = n-sn[weizhi-1];//本堆的个数

        LL r = findd2(tt,weizhi);

        //printf("R:%I64d\n",r);

        if(p[r] == tt)
        {
            printf("%I64d %I64d %I64d\n",weizhi,r,r);
        }
        else
        {
            if(p[r] < tt)
                r++;
            LL c = tt - p[r-1];
            printf("%I64d %I64d %I64d\n",weizhi,r,c);
        }
        /*else
        {
            LL c = tt - p[r-1];
            printf("%I64d %I64d %I64d\n",weizhi,r,c);
        }*/
    }
    return 0;
}

/*
2
14
15
*/
时间: 2024-10-10 23:51:06

HDU 2446 Shell Pyramid(二分查找 数学)的相关文章

【二分】 HDU 2446 Shell Pyramid

题意:很多球组成一个金字塔 第x层有 x*(x+1)/ 2 个球 给你一个S 表示金字塔一层一层数下来的第S个球 它在哪一层  这层中的第几行 第几列 公式 1 : x*(x+1)*(x+2)/ 6 公式 2 :x*(x+1)/ 2 公式1为公式2 的前n项和 #include <cstdio> #include <cstring> #include <cstdlib> #include <string> #include <iostream>

hdu 4768 Flyer(二分查找)

Flyer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1537    Accepted Submission(s): 552 Problem Description The new semester begins! Different kinds of student societies are all trying to adv

hdu 5249 KPI 【二分查找】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5249 分析:这道题是2015百度之星初赛1的4题 这道题不算太难当时队友做出来了,不过费了老大劲,其实我从中能够吸取教训的, 原因是,我一看这道题就是数据结构的,然后和队友想的一样二分查找,但是从中 遇到了一系列的问题: 首先储存数据我们不能用带有下标的数组,因为题目中的数据是可删可添的这样如果用 数组的话时间复杂度是相当高的,因为如果按大小插入,就要移动其他数据,如果在 尾部添加,就要对其排序,因

HDU 3763 CD【二分查找】

解题思路:给出两个数列an,bn,求an和bn中相同元素的个数因为注意到n的取值是0到1000000,所以可以用二分查找来做,因为题目中给出的an,bn,已经是单调递增的,所以不用排序了,对于输入的每一个b[i],查找它在an数列中是否存在.存在返回值为1,不存在返回值为0 CD Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 627

二分查找+数学 HDOJ 4342 History repeat itself

题目传送门 题意:计算从1开始到第n个非完全平方数的开方和 分析:设第n个非完全平方数的值为a,x * x < a < (x+1) * (x+1),而且易得(tmp = sqrt (a) ) == x,a之前的非完全平方数的个数为a - tmp,所以可以二分查找a - tmp == n的a,然后模拟一下能计算出前a个数的开方和 收获:二分查找是个好方法 代码: /************************************************ * Author :Running

hdu 1969 Pie(贪心+二分查找)(简单)

Pie Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 5628    Accepted Submission(s): 2184 Problem Description My birthday is coming up and traditionally I'm serving pie. Not just one pie, no, I

hdu 1969 Pie(二分查找)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1969 Pie Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4513    Accepted Submission(s): 1819 Problem Description My birthday is coming up and trad

hdu 5312 三角形数 二分查找

Sequence Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 891    Accepted Submission(s): 271 Problem Description Today, Soda has learned a sequence whose n-th(n≥1) item is 3n(n?1)+1. Now he wa

HDU 6216 A Cubic number and A Cubic Number(数学/二分查找)

题意: 给定一个素数p(p <= 1e12),问是否存在一对立方差等于p. 分析: 根据平方差公式: 因为p是一个素数, 所以只能拆分成 1*p, 所以 a-b = 1. 然后代入a = b + 1. 求出 3a2 + 3a + 1 = p 化简得a(a+1) = (p-1)/3 令(p-1)/3 = T, 问题化为是否存在整数a使得a(a+1) == T, 那么令 t = (int)sqrt(T),只要判定一下t * (t+1) == T ? 即可 另一种做法是打一个a的表(a只要打到1e6)