Loading

HOJ 2058 The sum problem

HOJ 2058 The sum problem

Problem Description

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.

Input

Input contains multiple test cases. each case contains two integers N, M( 1 <= N, M <= 1000000000).input ends with N = M = 0.

Output

For each test case, print all the possible sub-sequence that its sum is M.The format is show in the sample below.print a blank line after each test case.

Sample Input

20 10
50 30
0 0

Sample Output

[1,4]
[10,10]

[4,8]
[6,9]
[9,11]
[30,30]

滑动窗口

本来觉得这题没难度,就滑动窗口直接做了。

#include "iostream"
#include "cstdio"

using namespace std;

__int32 min(__int32 x, __int32 y) {
    return x > y ? y : x;
}
int main() {
    __int32 N,M;
    __int32 left, right,sum;
    while (scanf("%d %d", &N,&M) != EOF) {
        if (N == 0 && M == 0)break;
        left = right = 1;
        sum = 1;
        while (right <= min(N,M)) {
            if (sum < M) {
				sum += ++right;
                continue;
            }
            if (sum == M) {
                printf("[%d,%d]\n", left, right);
            }
            if (sum >= M) {
                sum -= left++;
                continue;
            }
        }
        printf("\n");
    }
    return 0;
}

但是当数据量过大,还是会挂。

优化

看了别人的代码,优化了一下

题目是要求等差数列[1,N]中的某一段累加等于M,根据等差数列求和公式,也就是说我们要找到\(len\times a_1+\frac{len(len-1)d}{2}==M\)。(len是等差数列中的n,因为题中已有一个N,避免混淆。\(len=结束位置-起始位置+1\))

所以题目转换成了,我们找到一个起始位置和一个结束位置,如果满足上面的公式,则输出这两个位置。

但如果硬找起始位置和结束位置,我们发现还是要很高的复杂度,我们从长度入手,发现把上面的公式变化形态,得到这样的公式:

\[a_1\times len = M-\frac{len(len-1)}{2} \]

把这个数列所有可能的长度遍历一遍,就能求出\(a_1\)并且\(a_n=a_1\times len + len -1\)

#include "iostream"
#include "cstdio"

using namespace std;

int main() {
    int N,M,len,maxLen,t;
    while (scanf("%d %d", &N,&M) != EOF) {
        if (N == 0 && M == 0)break;
        maxLen = sqrt(M*2);
        for (len = maxLen; len > 0; len--) {
            t = M - len * (len - 1) / 2;
            if (t % len == 0)
                printf("[%d,%d]\n", t / len, t / len + len -1);
        }
        printf("\n");
    }
    return 0;
}
posted @ 2020-11-01 14:02  yudoge  阅读(152)  评论(0编辑  收藏  举报