微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

hdu 2446 Shell Pyramid


点击打开链接



题意:

题意很迷,看了很久才看懂。

他要堆炮弹,怎么堆呢,

递增的三角形的堆,例如

1 2 5 11 .。。。

3 4 6 7

8 9 10

然后给你一个炮弹编号, 问你在第几个三角形中,并且在该三角形的几行几列。


题解:

两种做法,

第一种二分,最省事。

打表求出前n堆的和and前n行的和。 二百多万的数组就差不多了。

二分堆,在二分行。

第二种推公式。

卧槽,,,推了俩小时!!!!。

前n行的公式很好求, n(n+1)/2;

前n堆麻烦点,

首先 1 2 3 4 5 6

1 4 10 20 35 56

1*1+0 2*2+0 3*3+1 4*4+3 5*5+10 6*6+20


于是发现 前n堆的和为 1-n 所有 和n同奇同偶的数的平方和 例 n=5; Sn=1*1+3*3+5*5;

这样还是不好总结公式。因为不连续,

那么把它变成连续的直接就有1^2+2^2+3^2+……+n^2=n(n+1)(2n+1)/6 。

那么可得 n*n->(n+1)*(n+1) 可得 吧 =Sn-1->Sn

Sn=(1*1+2*2+.....+n*n+1+2+......+n)/2;

Sn-1=(n*n*n-n)/6;

这样可以求出在第几个三角形,再求出在第几行,第几个即可。


#include<bits/stdc++.h>
#define ll long long
using namespace std;

int main(){
    int t;
    ll x,y,z,n;
    scanf("%d",&t);
    while(t--){
        scanf("%lld",&n);
        ll x=(ll)pow(n*6.0,1.0/3.0)+1;
        while(x*x*x-x>=n*6) x--;
        n-=(x*x*x-x)/6;
        y=(ll)sqrt(2.0*n)+1;
        while(y*(y+1)>=n*2) y--;
        z=n-y*(y+1)/2;
        printf("%lld %lld %lld\n",x,y+1,z);
    }
    return 0;
}

原文地址:https://www.jb51.cc/bash/392276.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐