hdu2058The sum problem(等差数列求和公式)

传送门

题目描述:

Given a sequence 1,2,3,......N, your job is to calculate all the possible sub-sequences that the sum of the sub-sequence is M.

思路:当然是滑动窗口啦,l,r不断移动,简单!

TLE....正解:观察区间的性质,是等差数列哒,所以某个区间的和可以表示为a+1,a+2,...a+d的和即找满足a*d+(d+1)*d/2=m的区间,

我们发现d^2是小于2*m的,于是我们就能枚举d,看求出的a是不是个整数,是整数说明就能找到一组区间,即[a+1,a+d],Orz...

滑动窗口TLE代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100005;
int main() {
    //freopen("test.txt", "r", stdin);
    bool f = 0;
    ll n, m;
    while (~scanf("%lld%lld", &n, &m)&&n) {
        if (f)printf("\n");
        f = 1;
        ll l = 1, r = 1;
        ll sum = 1;
        while (r <= n) {
            if (l > m)break;
            while (sum < m) {
                r++; sum += r;
            }
            if (sum == m) {
                printf("[%lld,%lld]\n", l, r);
                sum -= l; l++;
            }
            while (sum > m) {
                sum -= l; l++;
            }
        }
    }
    return 0;
}

等差求和公式AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100005;
int main() {
    int n, m;
    //freopen("test.txt", "r", stdin);
    while (~scanf("%d%d", &n, &m) && n) {
        int d, b,a;
        for (d = sqrt(2 * m); d >= 1; d--) {
            b = m - (1 + d) * d / 2;
            if (b % d == 0) {//看a是否是个正整数
                a = b / d;
                printf("[%d,%d]\n", a + 1, a + d);
            }
        }
        printf("\n");
    }
    return 0;
}

 

posted @ 2021-04-17 20:22  cono奇犽哒  阅读(125)  评论(0)    收藏  举报