标签:
源程序名 combo.??? (pas,c,cpp)
可执行文件名 combo.exe
输入文件名 combo.in
输出文件名 combo.out
对一个给定的自然数M,求出所有的连续的自然数段,这些连续的自然数段中的全部数之和为M。
例子:1998+1999+2000+2001+2002 = 10000,所以从1998到2002的一个自然数段为M=10000的一个解。
输入
包含一个整数的单独一行给出M的值(10 <= M <= 2,000,000)。
输出
每行两个自然数,给出一个满足条件的连续自然数段中的第一个数和最后一个数,两数之间用一个空格隔开,所有输出行的第一个按从小到大的升序排列,对于给定的输入数据,保证至少有一个解。
样例
combo.in
10000
combo.out
18 142
297 328
388 412
1998 2002
思路:将m因数分解,在判断该对因数能否作为答案输出。
(问我为毛是因数,学过等差数列么……)
program t2; type aa=record l,r:longint; end; var m,i,sum:longint; f:array[1..2000000]of aa; procedure pd(x,y:longint); var c:longint; begin if x mod 2=1 then begin if y mod 2=1 then begin c:=(y-1)div 2; if x>=c+1 then begin f[sum].l:=x-c; f[sum].r:=x+c; inc(sum); end; c:=y; if (x-1)div 2>=c then begin f[sum].l:=((x-1)div 2)+1-c; f[sum].r:=((x+1)div 2)-1+c; inc(sum); end; end; if y mod 2=0 then begin c:=y; if (x-1)div 2>=c then begin f[sum].l:=((x-1)div 2)+1-c; f[sum].r:=((x+1)div 2)-1+c; inc(sum); end; end; end; if x mod 2=0 then begin if y mod 2=1 then begin c:=(y-1)div 2; if x>=c+1 then begin f[sum].l:=x-c; f[sum].r:=x+c; inc(sum); end; end; end; end; procedure sort(l,r: longint); var i,j,x: longint; y:aa; begin i:=l; j:=r; x:=f[(l+r) div 2].l; repeat while f[i].l<x do inc(i); while x<f[j].l do dec(j); if not(i>j) then begin y:=f[i]; f[i]:=f[j]; f[j]:=y; inc(i); j:=j-1; end; until i>j; if l<j then sort(l,j); if i<r then sort(i,r); end; begin assign(input,‘combo.in‘); assign(output,‘combo.out‘); reset(input); rewrite(output); sum:=1; readln(m); for i:=2 to m-1 do if m mod i=0 then pd(i,m div i); if m mod 2=1 then begin inc(sum); f[sum].l:=(m-1)div 2; f[sum].r:=(m+1)div 2; end; sort(1,sum); for i:=2 to sum do writeln(f[i].l,‘ ‘,f[i].r); close(input); close(output); end.
好像暴力枚举也可以。
标签:
原文地址:http://www.cnblogs.com/liuxinyu/p/4889537.html