HDU 2446 Shell Pyramid 二分查找

今天上午终于把最后一题D题水掉了。我的二分也算是AK了了吧。
这题可以说我还是有版权的,嘿嘿~~越来越有意思了!
说一下怎么做吧。
听说有公式就试着自己推了一下,感觉不错呢。
首先我们可以看出

a1=1,a2=3,a3=6. 很显而易见的an=(1+n)*n/2;
那么Sn怎么求呢???Sn=∑an=(1/2)∑(n*n+n)=0.5*(∑n*n+∑n);
这样就转化为连续自然数平方的和与连续自然数的和了。
连续自然数和:(1+n)*n/2
平方的和公式:n(n+1)(2n+1)/2
立方的和公式:[n(n+1)/2]^2
将公式带入最终化简------>Sn=n(n+1)(n+2)/6; 很漂亮的一个公式诞生了

偷笑

接下来用二分来搜索答案就好了。
觉得自己的代码还是很美观的~虽然还有漏洞

#include<iostream>
#define MAXLayer 1111111
using namespace std;

__int64 layerSum[MAXLayer];

__int64 getSum( __int64 m )
{
 		__int64 sum;
 		sum=m*(m+1)/2;
	 	   if( sum%3==0 ){
   			   sum/=3;sum*=(m+2);
    	   }
    	   else sum*=(m+2)/3;
    	return sum;
}

int BinarySeachLayer( __int64 &num )
{
 	__int64 l=1,r=3810776,m;
 	__int64 sum;
 	while( m=(l+r)/2,l<r )
 	{
	 	   sum=getSum(m);
	 	   if( sum>=num ) r=m;
	 	   else l=m+1;
  	}
  	num-=getSum(m-1);
  	return (int)m;
}

int BinarySeachRow( __int64 &num )
{
 	__int64 l=1,r=3810776,m;
 	__int64 sum;
 	while( m=(l+r)/2,l<r )
 	{
	 	   sum=(1+m)*m/2;
	 	   if( sum>=num ) r=m;
	 	   else l=m+1;
  	}
  	num-=(m-1)*m/2;
  	return (int)m;
}
int main()
{
 	__int64 N;int T;
 	scanf( "%d",&T );
 	while( T-- )
 	{		
		   scanf("%I64d",&N);
	 	   int Layer=BinarySeachLayer( N );
	 	   int Row=BinarySeachRow( N );
	 	   int Column=N;
	 	   printf( "%d %d %d\n",Layer,Row,Column );
  	}
  	return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值