1、題目(**於洛谷):
2、主要思想:
方法一:
①先想到雙重迴圈暴力列舉
②發現可以將列舉區間右端縮小為m的一半,因為從m / 2 + (m / 2 + 1)開始後面都會大於m
③又發現因為可以用雙指標,當列舉到s[j] - s[i - 1] == m或者s[j] - s[i - 1] > m時可以直接跳出迴圈,列舉下乙個 i 。
④用字首和優化計算子串行和的部分
方法二:
用代數方法根據數列前n相項合公式,發現(l + r)* (r - l + 1) / 2 = m。
設k1 = l + r, k2 = r - l + 1,可得r = (k1 + k2 - 1) / 2, l = (k1 - k2 + 1) / 2;(l + r)* (r - l + 1) = 2 * m。
因為l 和 r 均為整數而k1 + k2 = 2 * r + 1(奇數)所以k1 和k2 一定一奇一偶;因為 l != r 所以 (k1 + k2 - 1) / 2 != (k1 - k2 + 1) / 2, 可得k2 != 1。
將問題轉化為列舉k1,k2
3、c++**如下:
方法一:
#include
using
namespace std;
const
int n =
1000010
;int m;
int s[n]
;//s為字首和陣列
intmain()
if(s[j]
- s[i -1]
> m)
break
;//當s[j] - s[i - 1]已經大於 m 時,j再+1的話,序列和一定會大於m,後面不必再列舉}}
return0;
}
方法二:
#include
#include
using
namespace std;
intmain()
}return0;
}
注意事項:
題中m從10開始,對0似乎沒有特殊要求(感覺0 4和1 4都能得10),但是算上0又不能ac,就直接從1開始了。
洛谷P1147 連續自然數和
連續自然數和 題目描述 對乙個給定的自然數m,求出所有的連續的自然數段,這些連續的自然數段中的全部數之和為m m 2000000 例子 1998 1999 2000 2001 2002 10000,所以從1998到2002的乙個自然數段為m 10000的乙個解。分析可以把連續自然數段看成乙個等差數列...
洛谷 P1147 連續自然數和
對乙個給定的自然數m,求出所有的連續的自然數段,這些連續的自然數段中的全部數之和為m。例子 1998 1999 2000 2001 2002 10000,所以從1998到2002的乙個自然數段為m 10000的乙個解。包含乙個整數的單獨一行給出m的值 10 m 2,000,000 每行兩個自然數,給...
洛谷 P1147 連續自然數和
前言 只為轉c 而寫個解題報告。題目描述 對乙個給定的自然數m,求出所有的連續的自然數段,這些連續的自然數段中的全部數之和為m。例子 1998 1999 2000 2001 2002 10000,所以從1998到2002的乙個自然數段為m 10000的乙個解。輸入格式 包含乙個整數的單獨一行給出m的...