HDU 2058 The sum problem

最近开始做水题了-_-#…… 这个题居然交了好多次才过,因为一些小问题,错了好多次…… 一直说要注意细节,看来这种功夫并非一朝一夕能够习得的呀。

题意:

  求所有和为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 }
View Code
原文地址:https://www.cnblogs.com/Phantom01/p/3650261.html