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;
}