hdu 2446 Shell Pyramid(GOD = =)

开始想打表二分来着,后来想试试能不能推出来公式,结果还真推出来了 = =,很简单的公式。

第n-1堆的最大的序号是,(n*n*n - n)/6。

然后对n*6开立方根可以得到n(细节细节)。。。

再找到这一堆的大小(细节细节)。。

再根据1+2+3。。。求和公式找到第几行(细节细节)。。

再根据前N行的和找到在第N+1行的第几列(细节细节)。。。

= = 。。注意别超unsigned __int64。。中间可以用double计算防超。不过显然数据很小。。


#include <map>
#include <set>
#include <queue>
#include <stack>
#include <math.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
#define MID(x,y) ( ( x + y ) >> 1 )
#define L(x) ( x << 1 )
#define R(x) ( x << 1 | 1 )
#define BUG puts("here!!!")
#define STOP system("pause")

using namespace std;

typedef unsigned __int64 ll;
int main()
{
	int ncases;
	ll n;

	scanf("%d", &ncases);
	
	while( ncases-- )
	{
		scanf("%I64u", &n);
		ll p = (ll)pow(n*6.0, 1.0/3);
		
		p++;
		while( (p*p*p - p) >= n*6.0 ) p--;
		n -= (p*p*p - p)/6;
		
		ll k = (ll)(sqrt(2.0*n));
		
		k++;
		while( k*(k+1)/2 >= n ) k--;
		
		ll ans1 = k + 1;
		ll ans2 = n - k*(k+1)/2;
		printf("%I64u %I64u %I64u\n", p, ans1, ans2);
	}
	
return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值