• 剑指Offer


    剑指Offer - 九度1354 - 和为S的连续正数序列
    2013-11-23 02:02
    题目描述:

    小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!

    输入:

    输入有多组数据。

    每组数据仅包括1个整数S(S<=1,000,000)。如果S为负数时,则结束输入。

    输出:

    对应每组数据,若不存在和为S的连续正数序列,则输出“Pity!”;否则,按照开始数字从小到大的顺序,输出所有和为S的连续正数序列。每组数据末尾以“#”号结束。

    样例输入:
    4
    5
    100
    -1
    样例输出:
    Pity!
    #
    2 3
    #
    9 10 11 12 13 14 15 16
    18 19 20 21 22
    #
    题意分析:
      题目要求求出对于一个数S,有多少种不同的连续正数序列加起来等于这个数S,数列至少要两个数。
      比如
        12 = 3 + 4 + 5
        13 = 6 + 7
      对于n个数a, a + 1, a + 2, ..., a + n - 1,加起来和sum = (a + a + n - 1) * n / 2;
      所以对于某些n,我们要求2 * S = (2 * a + n - 1) * n的整数解。
      因为题目要求所有数都是正整数,所以a >= 1,2 * a + n - 1 >= n + 1 > n,于是n < sqrt(2 * S),确定了范围限制在sqrt(1000000)内,也就是1000。,程序效率不成问题
      对于2至[sqrt(2 * S)]的整数n,对应判断每一个能否求出整数解即可。有整数解的话,输出对应的连续数列。
      注意题目要求按照开始数字从小到大输出结果。开头数字越小,项数也就越多,n也就越大,所以n要从sqrt(2 * S)往下递减。
      时间复杂度O(sqrt(S)),空间复杂度O(1)。
     1 // 652789    zhuli19901106    1354    Accepted    点击此处查看所有case的执行结果    1032KB    787B    80MS
     2 // 20131172038
     3 #include <cmath>
     4 #include <cstdio>
     5 using namespace std;
     6 
     7 int main()
     8 {
     9     int x, y;
    10     int tmp;
    11     int s;
    12     int res_count;
    13     int i;
    14     
    15     while(scanf("%d", &s) == 1 && s >= 0){
    16         if(s < 3){
    17             printf("Pity!
    #
    ");
    18             continue;
    19         }
    20         
    21         s *= 2;
    22         x = (int)sqrt(s);
    23         res_count = 0;
    24         while(x >= 2){
    25             if(s % x == 0){
    26                 y = s / x;
    27                 if(y - x + 1 > 0 && ((y - x + 1) & 0x1) == 0){
    28                     ++res_count;
    29                     tmp = (y - x + 1) >> 1;
    30                     printf("%d", tmp);
    31                     for(i = tmp + 1; i < tmp + x; ++i){
    32                         printf(" %d", i);
    33                     }
    34                     printf("
    ");
    35                 }
    36             }
    37             // watch out for the result order
    38             --x;
    39         }
    40         if(res_count <= 0){
    41             printf("Pity!
    ");
    42         }
    43         printf("#
    ");
    44     }
    45     
    46     return 0;
    47 }
  • 相关阅读:
    leetCode 78.Subsets (子集) 解题思路和方法
    大话设计模式C++版——代理模式
    不用加减乘除做加法
    hdu 1257
    小学生算术
    字符串排序问题
    POJ 2421 Constructing Roads
    http://vdceye.com/ 全新页面上线
    POJ3262 Protecting the Flowers 【贪心】
    集群环境下JSP中获取客户端IP地址的方法
  • 原文地址:https://www.cnblogs.com/zhuli19901106/p/3438566.html
Copyright © 2020-2023  润新知