2013 年校赛C题 小明的积木

来源:互联网 发布:不需要域名的企业邮箱 编辑:程序博客网 时间:2024/05/18 16:56

C小明的积木

Time Limit: 1000MS

Description

小明最近迷上了积木,喜欢用积木堆成各种形状的模型。但是,在无意之中,他发现一个有趣的问题,假设给他一定数量的积木,他可以把这些积木分成多个连续的整数个积木(至少是两个),不过,后来他又发现,情况不止一种!例如:给小明15个积木,小明能很快的找出这些情况:15 = 1 + 2 +3 + 4+ 5 = 4 + 5 + 6  = 7 + 8,小明能把所有的三种情况都找出来。现在问题来了,假设有任意的给定积木数n,是否存在多个连续的整数个积木的和,如果存在,求出有多少种情况符合条件,把所有的列举出来。

Input:

输入的第一行为一个正整数t ( t<=10000 ),表示有t组测试数据。每组数据为一个数n,表示积木数 (0 <= n <= 1000000000).

Output:

对每组数据,输出所有符合条件的情况,把数字从小到大的情况列举出来!每种情况按一行输出。如果不存在,就输出No

Sample Input:

 3

15

 3

 4

Sample Output:

 1 2 3 4 5

 4 5 6

 7 8

 1 2

 No

      

当时时间范围给了5秒 暴力过了

后来 可以(1) 以长度为范围进行遍历 O(n) 的算法  因为数据量好大,这个能跑 2213ms

采用的公式 n*(n+1)=2*sum

(2)还有可以扫一遍,多了的数就从前面减去,少了的话就从后面加上。


          

post code: 第一种方法

#include<stdio.h>#include<math.h>int main(){    int n,num,begin,i,j,k;    scanf("%d",&n);        while(n--){       scanf("%d",&num);       num=num*2;       begin=(int)sqrt( (double) num);       int time=0;       for(i=1;i<=num/4;i++){          //注意从原数的一半开始 这样就不会漏掉 样例中 7,8的情况            for(j=2;j<=begin;j++){         //  注意这是根号n               if( (i+i+j-1)*j==num ){                  time=1;                  for(k=i;k<=i+j-1;k++){                     printf("%d",k);                     if(k!=i+j-1)printf(" ");                  }                  printf("\n");               }             }                                                }               if(time==0)printf("No\n");            }    return 0;}