对于一个正整数,输出它所有可能的连续自然数之和的算式
1+2=3
4+5=9
2+3+4=9
根据题意,有:
s+(s+1)+(s+2)+...+(s+k) = n
(k+1)s + (k+1)k/2 = n
(k+1)(2s+k)=2n
s = (2n/(k+1)-k)/2
因为 s, k都是整数,所以应满足2n%(k+1)==0 && (2n/(k+1)-k)%2==0
void Print(int n, int s, int k) { printf("%d=",n); for (int i=s; i<=s+k; i++) { if (i==s) printf("%d", i); else printf("+%d",i); } printf("\n"); } void Decompose(int n) { int up=(int)sqrt((long double)2*n); for (int k=1; k<up; k++) { if ( 2*n%(k+1)==0 && (2*n/(k+1)-k)%2==0 ) { int s=(2*n/(k+1)-k)/2; Print(n, s, k); } } }
时间复杂度:O((2n)^0.5)
void Decompose2(int n) { int start, end, sum; start = 1, end = 1, sum=0; int up = (n+1)>>2; while (end<=up) { sum += end; if (sum == n) { Print(n, start, end-start); sum -= start++; end++; } else if (sum < n) { end++; } else { sum -= end; sum -= start++; } } }
时间复杂度:O(n) 但只用到加减法
子序列数目最多的数是哪一个?
子序列最多这一点可以推断出该序列一定是从1开始的,那么就有
(k+1)k/2 <= INT_MAX
k = sqrt(2*INT_MAX);
if ( (k+1)k/2 > INT_MAX)
k--;