题解报告:hdu 2058 The sum problem

Posted 霜雪千年

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解报告:hdu 2058 The sum problem相关的知识,希望对你有一定的参考价值。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2058

问题描述

  给定一个序列1,2,3,...... N,你的工作是计算所有可能的子序列,其子序列的总和为M.  

输入

  输入包含多个测试用例。 每个情况包含两个整数N,M(1 <= N,M <= 1000000000)。输入以N = M = 0结束。  

输出

   对于每个测试用例,打印其总和为M的所有可能的子序列。格式显示在下面的示例中。在每个测试用例后打印一个空行。  

示例输入

20 10

50 30

0 0  

示例输出

[1,4]

[10,10]

 

[4,8]

[6,9]

[9,11]

[30,30]

解题思路:这道题要转换一下角度来思考,否则会一直WA~_~。。

不妨假设i为区间左值,j为区间元素个数(j至少为1),则区间为[i,i+j-1]。

若这个区间合法,那么由等差数列求和公式,得(i+(i+j-1))*j/2==M(1式),即(2*i+j-1)*j/2==M(2式),故得i=(2*M/j-j+1)/2,

将i,j代回2式,若1式成立则[i,i+j-1]满足条件。注意j最小为1,(区间右值大于或等于区间左值),而由2式,得(j+2*i)*j=2*M,

由题目条件得i>=1,则j*j<=2*M,即j<=(int)sqrt(2*M)。综上,遍历区间长度j即可。

AC代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main()
 4 {
 5     int N,M,i,j;//数学规律,等差数列
 6     while(cin>>N>>M && (N+M)){
 7         for(j=(int)sqrt(2*M);j>0;j--){
 8             i=(2*M/j-j+1)/2;//推导出来的公式
 9             if(j*(2*i+j-1)/2==M)cout<<[<<i<<,<<i+j-1<<]<<endl;//把i,j分别代入推导出来的表达式看是否相等
10         }
11         cout<<endl;//每个测试后面空出一行
12     }
13     return 0;
14 }

 

以上是关于题解报告:hdu 2058 The sum problem的主要内容,如果未能解决你的问题,请参考以下文章

hdu 2058 The sum problem

HDU 2058 The sum problem

HDU - 2058 - The sum problem

HDU 2058 The sum problem (数学+暴力)

HDU - 2058 The sum problem(简单数学题)

题解报告:hdu 1032 The 3n + 1 problem