1. 程式人生 > >[51nod1138]正整數分解為幾個連續自然數之和

[51nod1138]正整數分解為幾個連續自然數之和

sqrt esp 連續 奇數 mes 判斷 -i 兩個 註意

解題關鍵:註意為什麽上界是$\sqrt {2n} $

因為函數是關於m的遞減函數,而結果必須為正整數

$a = \frac{{2n + m - {m^2}}}{{2m}} = \frac{n}{m} + \frac{1}{2} - \frac{m}{2}$

將$\sqrt {2n} $帶入,結果為$\frac{1}{2}$,正好保證了結果不為負,因為函數是單調遞減的,所以也不需判斷結果是否為負。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 int main(){
5 int n; 6 cin>>n; 7 bool flag=false; 8 int t=sqrt(2*n); 9 for(int i=t;i>=2;i--){ 10 int t1=2*n+i-i*i; 11 int t2=2*i; 12 if(t1%t2==0){ 13 flag=true; 14 cout<<t1/t2<<endl; 15 } 16 } 17 if
(!flag) cout<<"No Solution\n"; 18 return 0; 19 }

第二個問題是什麽樣的數可以寫成連續n個自然數之和,什麽樣的數不能?
通過編程實驗發現,除了2^n以外,其余所有數都可以寫成該形式。下面說明為什麽。
若數M符合條件,則有M=a+(a+1)+(a+2)+…+(a+n-1)=(2*a+n-1)*n/2,而2*a+n-1與n肯定一個為奇數一個為偶數,即M一定要有一個奇數因子,而所有2^n都沒有奇數因子,因此肯定不符合條件。
再證明只有M有一個奇數因子,即M!=2^n,M就可以寫成連續n個自然數之和。假設M有一個奇數因子a,則M=a*b。

1)若b也是奇數,只要b-(a-1)/2>0,M就可以寫成以b-(a-1)/2開頭的連續a個自然數;將這條結論裏的a和b調換,仍然成立。15=3*5=1+2+3+4+5=4+5+6.
2)若b是偶數,則我們有一個奇數a和一個偶數b。
2.1)若b-(a-1)/2>0,M就可以寫成以b-(a-1)/2開頭的連續a個自然數。24=3*8=7+8+9.
2.2)若(a+1)/2-b>0,M就可以寫成以(a+1)/2-b開頭的連續2*b個自然數。38=19*2=8+9+10+11.
上述兩個不等式必然至少有一個成立,所以可以證明,只要M有一個奇數因子,就一定可以寫成連續n個自然數之和。

[51nod1138]正整數分解為幾個連續自然數之和