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.
20 10 50 30 0 0
[1,4] [10,10] [4,8] [6,9] [9,11][30,30]
题解:题目要求在1至m的所有数中,找到所有的连续的子序列,其和都为n;
一开始的想法是从每个点开始遍历查找以这个点为左端点的满足要求的序列是否存在
结果代码超时,这时便需要换个思路,不是从左端点入手,而是从子序列长度入手,这样可以大大降低消耗时间,如果左端点为i,长度为k,那么公式为:((2*i)+k-1)*k = 2*n;int i,j,sum = 0,k; /* for(i = 1; i <= m; i++)//从1开始查找子序列 { sum = 0; for(j = i; j <= n; j++)//查找以i为开始的子序列是否满足条件 { sum = sum + j; if(sum == n) { printf("[%d,%d]\n",i,j); } if(sum > n)break; } } */
对k进行初始化的时候,是把i设初值为1,因为这样序列长度才会最长,当然不一定存在这样的序列,这就需要验证,验证的方法是通过整数除法所得到的值会舍去小数部分,这样无法整除的数便会被筛选出来,
代码如下:
#include<stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> int xulie(int m,int n) { int i,j,sum = 0,k; k = sqrt(n * 2); k++; while(--k) { i = n/k - (k - 1)/2; if((2 * i + k - 1 ) * k == 2 * n) { printf("[%d,%d]\n",i,i + k - 1); } } return 0; } int main() { int m,n; scanf("%d%d",&m,&n); while(m != 0||n != 0) { xulie(m,n); printf("\n"); scanf("%d%d",&m,&n); } }