HDU 2058 The sum problem [数学]

本文介绍了一种求解连续子序列和等于给定值M的算法,通过枚举子序列长度并计算起始位置的方法解决该问题。文章提供了完整的算法思路及C++实现代码。

从今天开始 水题再不记!
凡是记得题,都是不水的。

Description

输入N M
在1..N中找到连续字串的和==M
每一个输出之后空一行

Sample Input

20 10
50 30
0 0

Sample Output

[1,4]
[10,10]

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

Algorithm

数学题
设要输出的 [x,x+y]
则有
(x + x+y)*(y+1)/2 = M
2M = (2x+y)*(y+1)
2M = 2x(y+1) + y(y+1)
x = (2M-y(y+1))/2(y+1)
x = M/(y+1) - y/2
枚举y就可以找到x
当然了,一开始还有点问题,比如以为y不需是2的倍数,看Sample不就知道不是了= =
当然了,y的范围一开始也没确定,以为是sqrt(m),然后WA
在王老师的指导下继续满足x>0
则有
x = M/(y+1) - y/2 > 0
M - (y+1)y/2 > 0
y(y+1) < 2M
大概sqrt(2M)+1可以吧,我提交的时候改成了+10

Code

#include <cmath>
#include <cstdio>
#include <iostream>
#include <climits>
using namespace std;
int main()
{
//  freopen("input.txt", "r", stdin);
  for (;;) {
    long long n, m;
    scanf("%lld%lld", &n, &m);
    if (n == 0 && m == 0) break;
    int i = sqrt(2 * m) + 1;
    for (; i >= 0; i--) {
        double x = double(m)/(i + 1) - double(i)/2;
        if (x > 0 && x + i <= n && x == floor(x)) {
          long long ansx = floor(x);
          printf("[%lld,%lld]\n", ansx, ansx + i);
        }
    }
    printf("\n");
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值