最近开始做水题了-_-#…… 这个题居然交了好多次才过,因为一些小问题,错了好多次…… 一直说要注意细节,看来这种功夫并非一朝一夕能够习得的呀。
题意:
求所有和为M的,值小于等于N的连续整数区间。
思路:
如果我们假定区间的起点为st, 长度为l, 那么 st + (st+1) + …… + (st+l-1) = (st + (st+l-1)) * l / 2 = (2*st - 1 + l) * l/ 2。
于是得到一个不定方程:M = (2*st - 1 + l) * l/ 2 , (1<=st<=N)。
然后就枚举l求这个方程的整数解。
我们可以发现其中st, l都是正数,所以 2*M = (2*st - 1 + l) * l = (l*l) + 2*st*l - l > l*l。 所以l只需要枚举到 sqrt(2*m)就行了。
代码:

1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <cmath> 5 6 using namespace std; 7 8 int main() { 9 #ifdef Phantom01 10 freopen("HDU2058.txt", "r", stdin); 11 #endif // Phantom01 12 13 int n, m; 14 while (scanf("%d%d", &n, &m)!=EOF) { 15 if (0==n && 0==m) break; 16 m *= 2; 17 int len = min(n, (int)(sqrt((double)m)+0.5)); 18 for (int i = len; i > 0; i--) if (0 == m%i && 0==(m/i-i+1)%2) { 19 int st = (m/i-i+1)/2; 20 if (1<=st && (st+i-1)<=n) { 21 printf("[%d,%d] ", st, st+i-1); 22 } 23 } 24 puts(""); 25 } 26 27 return 0; 28 }