Chinaunix首页 | 论坛 | 博客
  • 博客访问: 624338
  • 博文数量: 127
  • 博客积分: 6136
  • 博客等级: 准将
  • 技术积分: 1461
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-24 00:32

分类:

2010-07-20 15:28:13

问题1. 写一个程序,对于一个64位正整数,输出它所有可能的连续自然数(两个以上)之和的算式;

问题1分析:

假设这个正整数n可以表示成2个以上的连续自然数之和,那么可以设这个序列为a,a+1....a+i。那么n=a+(a+1)+...+(a+i)=(i+1)*a + (i+1)*i/2。如果我们可以确定i的范围,那么我们就可以遍历i,对于所有的i的取值,得到对应的a的值,然后判断a是否为整数,即可知是否符合要求。这里i可以认为表示的是序列的长度,那么最长的序列必然是n=1+2...+i。所以有i*(i+1)=2n。解得i=(sqrt(8n+1)-1)/2,所以i的取值就是[1, (sqrt(8n+1)-1)/2]区间中。随即,遍历i的取值,然后判断对应的a是否为整数即可。

代码如下:

#include <stdio.h>
#include <math.h>
#include <unistd.h>
#include <stdlib.h>

#define ZERO 0.000001L

int main(int argc, char *argv[])
{
    long long n, i, j, k;
    float temp, a;
    char equal[1000] = {0};
    if(argc < 2)
    {
        printf("usage:%s \n", argv[0]);
        exit(1);
    }
    n = atoi(argv[1]);
    j = (sqrt(8*n+1) - 1) / 2;
    for(i=1; i<=j; i++)
    {
        temp = (n*1.0)/(i+1) - (1.0*i)/2;
        a = temp - (long long)temp;
        if(a < ZERO && temp > ZERO)
        {
            sprintf(equal, "%ld=%ld", n, (long long)(temp));
            for(k=1; k<=i; k++)
            {
                sprintf(equal, "%s+%ld", equal, (long long)(temp+k));
            }
            printf("%s\n", equal);
        }
    }
    return 0;
}

编译,执行:
[root@localhost bczm]# gcc int.c -o m -lm
[root@localhost bczm]# ./m 100
100=18+19+20+21+22
100=9+10+11+12+13+14+15+16
[root@localhost bczm]#

阅读(1792) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~