今天上午終於把最後一題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 1111111using 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;}