hdu---2058The sum problem

来源:互联网 发布:专业淘宝拍摄 编辑:程序博客网 时间:2024/05/01 10:53

The sum problem

Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 13512    Accepted Submission(s): 4074


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 1050 300 0
 

 

Sample Output
[1,4][10,10][4,8][6,9][9,11][30,30]

 

 

//一开始想递归求解的思路就是错误的,因为n、m太大了,这里肯定是不能用递归来解答的。

//后来想到从前向后,设置两个变量标志数组起始位置和终止位置,进行一遍遍历即可: 将递归改为非递归!

//但是!!  超时!  

代码:

#include <stdio.h>#include <string.h>#include <math.h>#include <stdlib.h>#define N 1001000int n,m;int main(){    int i,j,k=0;    //freopen("in.txt","r",stdin);    while(scanf("%d %d",&n,&m)){        if(k) printf("\n");        if(n==m && n==0) break;        int front=1,last=1;int num=1;        while(front<=last){            if(num==m)                printf("[%d,%d]\n",front,last);            if(num<m){                last++;                num=num+last;            }            else{                num=num-front;                front++;            }        }        k=1;    }    return 0;}

 

//之后又想,既然一遍遍历都超时,那肯定就是有什么公式在里面了,换句话说也就是这个题目是有技巧的,需要进一步约减计算步骤。

// 既然要约减,这里肯定就是要去减少枚举量,这样才能顺利解决。

//思路:

  我们之前是枚举的区间开头和结尾! 现在我们枚举区间长度!  这样可以使枚举量降低一个层次!从而达到顺利解决问题的目的。

而当首项为1时,区间长度最长,可知区间最长为: int len=sqrt((double)(m)*2.0); 

之后枚举区间长度来求解即可!

代码:

#include<iostream>using namespace std; #include<math.h>int main(){ int n,m,i,j; while(scanf("%d%d",&n,&m) && (n||m)){   int len=sqrt((double)(m)*2.0);   while(len)  {     int a=m/len-(len-1)/2;     int b;     if(a*len+(len-1)*len/2==m)    {       printf("[%d,%d]\n",a,a+len-1);    }     len--;  }printf("\n");} return 0;}

 

//下面是一开始递归的想法,想去递归求解,但因为n、m过大,肯定爆栈,觉得脑子抽抽了才会去写这个递归的代码...

错误代码:

#include <stdio.h>#include <string.h>#include <math.h>#include <stdlib.h>#define N 1001000int n,m;void Cha(int a,int b,int num){    if(a>b) ;    else        if(a>n || b>n) ;        else{            if(num==m) printf("[%d,%d]\n",a,b);            if(num>m)  Cha(a+1,b,num-a);            else  Cha(a,b+1,num+b+1);        }}int main(){    int i,j,k=0;    freopen("in.txt","r",stdin);    while(scanf("%d %d",&n,&m)){        if(k) printf("\n");        if(n==m && n==0) break;        int front=1,last=1;        Cha(front,last,1);        k=1;    }    return 0;}

 

 

0 0
原创粉丝点击