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

题意:求出所有的情况,等差上去可以达到m值。

原来想着暴力搜索,但是题中的数据太大,所以时间超限。

百度了一下,发现可以套公式。

等差求和公式:

Sn=(a1+aN)*n/2
    =(a1+a1+d(n-1))*n/2
    =a1*n+d(n-1)*n/2;
因为此处公差d=1,所以Sn=a1*n+(n-1)*n/2,当从第一项开始算起时(因本题首项为1,即a1=1时),Sn=M时的项的个数n最多;
a1=1,现在又可化简为Sn=n+(n-1)*n/2=(n+1)n/2;
由题意得M=Sn,N为项的个数,则N<=n(max)=sqrt(Sn*2)=sqrt(M*2);
因此原式M=Sn =a1*n+(n-1)n/2=a1*N+(N-1)N/2,可得a1*N=M-(N-1)N/2;
数据都已经全了,现在只要遍历n(max)以内项数中,Sn=M的个数即可。
那么如何判断Sn=M呢?也就是判断a1*N=Sn-(N-1)N/2;得到的a1*N这个数能否被N整除,因为整除的话,说明首项存在于序列

#include<stdio.h>
#include<math.h>
int main(){
      int N,M,i,n,m;
      while(scanf("%d%d",&N,&M)!=EOF){
          if(N==0&&M==0) break;
       n=sqrt((double)(M)*2);
       while(n){
        m=M/n-(n-1)/2;
        if(m*n+(n*(n-1)/2)==M)
        printf("[%d,%d]\n",m,m+n-1);
        n--;
          }
          printf("\n");
      }
  return 0;
}
时间: 2024-12-15 01:42:25

HDU - 2058 The sum problem(简单数学题)的相关文章

hdu 2058 The sum problem(数学题)

题意:求[1,n]的子区间,使得子区间的元素和为m 代码: #include<cstdio> #include<cstring> #include<cmath> using namespace std; int main() { int n,m; while(scanf("%d%d",&n,&m)&&(n||m)) { for(int j=(int)sqrt(2*m);j>=1;j--) { int i=(2*m

hdu 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 <= 100000000

hdu - 2058 The sum problem (数学题)

http://acm.hdu.edu.cn/showproblem.php?pid=2058 求1-N多少个连续字段和等于M. 假设 从i开始长度为k的字段和等于M,那么 ( i+  i+k-1) * k/2=M即(2*i+k-1)*k==2M   那么 从k<= sqrt(2*M); i=M/k-(k-1)/2.这样通过从大到小枚举k的长度,并同时计算i的值判断和是否等于M,输出即可. 注意从(2*i+k-1)*k==2M这个式子得出的是k<=sqrt(2*M)而不是i,这样是为了方便计算,

hdu 2058 The sum problem (数学问题)

题目意思: http://acm.hdu.edu.cn/showproblem.php?pid=2058 给出n和m,在小于n的数中,找出连续的序列,使其和为m,并从小到大输出. 题目分析: 第一次见这种题,就模拟,很显然超时了,后来在<短码之美>上看到了好的解决方法,和详细讲解,现在我只会用,不知道怎么说明白了,我也是醉了... AC代码: /** *@xiaoran */ #include<iostream> #include<cstdio> #include<

HDU 2058 The sum 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).i

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

题意:给定一个N和M,N表示从1到N的连续序列,让你求在1到N这个序列中连续子序列的和为M的子序列区间. 析:很明显最直接的方法就是暴力,可是不幸的是,由于N,M太大了,肯定会TLE的.所以我们就想能不能优化一下,找一个范围.想到这是一个连续的序列而且是从1开始的,这不就是一个等差数列么,公差是1罢了.由求和公式得Sn = (a1+an) * n / 2;所以说n最大就是sqrt(M*2)(想一想为什么),因为a1+an 一定是大于n的.如果我们取区间的和,那么Sn = (ai+aj) * (j

hdu 1016 Prime Ring Problem (简单DFS)

Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 25700    Accepted Submission(s): 11453 Problem Description A ring is compose of n circles as shown in diagram. Put natural numb

hdu 2576 Another Sum Problem

题目大意:求前n项和的前n项和. 数学推导题,f(n)=n*(n+1)*(n+2)/6 推导思路如下: #include"cstdio" #include"cstring" #include"cmath" #include"cstdlib" #include"iostream" #include"algorithm" #include"queue" using nam

HDU ACM 2740 Root of the Problem 简单数学题

题意:求A,使得A^N最接近B. 分析:A=B^(1/n),对其上下取整,在各取N次幂,取最接近B的. #include<iostream> #include<cmath> using namespace std; int main() { int B,N,p,q; double tmp; while(cin>>B>>N && (B||N)) { tmp=pow(1.0*B,1.0/N); p=floor(tmp); //向下取整 q=cei