LQ0052 冰雹数枚举+角谷猜想

Posted 海岛Blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LQ0052 冰雹数枚举+角谷猜想相关的知识,希望对你有一定的参考价值。

题目来源:蓝桥杯2016初赛 C++ C组G题

题目描述
任意给定一个正整数N,如果是偶数,执行: N / 2;如果是奇数,执行: N * 3 + 1
生成的新的数字再执行同样的动作,循环往复。
通过观察发现,这个数字会一会儿上升到很高,一会儿又降落下来。
就这样起起落落的,但最终必会落到“1”
这有点像小冰雹粒子在冰雹云中翻滚增长的样子。
比如N=9:9,28,14,7,22,11,34,17,52,26,13,40,20,10,5,16,8,4,2,1
可以看到,N=9的时候,这个“小冰雹”最高冲到了52这个高度。

输入格式
输入存在多组测试数据,对于每组测试数据输入一行包含一个正整数N(N<1000000)

输出格式
对于每组测试数据,输出一行包含一个正整数表示答案

输入样例
10
100
输出样例
52
9232

问题分析
这个题实际上是角谷猜想的变形。
这个题的描述有BUG,其意思是对于给定的N, 从1-N计算角谷猜想的数列,找出最大值。
对于输出的N,用暴力法来实现是一种方法,但是会有很多重复的计算。
采用打表法会快许多。
需要注意的是,有可能数会比较大,要用long long类型。

AC的C语言程序(打表法)如下:

/* LQ0052 冰雹数 */

#include <stdio.h>
#include <string.h>

#define N 1000000 + 1
long long a[N];

long long geta(int n)

    long long t = n, maxt = n;
    while (t != 1) 
        if (t % 2 == 0)
            t /= 2;
        else
            t = t * 3 + 1;
        if (t <= N && a[t] != 0) 
            maxt = a[t] > maxt ? a[t] : maxt;
            return maxt;
        
        maxt = t > maxt ? t : maxt;
    
    return maxt;


int main()

    memset(a, 0, sizeof a);
    a[1] = 1;
    for (int i = 2; i <= N; i++) 
        long long t = geta(i);
        a[i] = a[i - 1] > t ? a[i - 1] : t;
    

    int n;
    while (~scanf("%d", &n))
        printf("%lld\\n", a[n]);

    return 0;

AC的C语言程序(暴力)如下:

/* LQ0052 冰雹数 */

#include <stdio.h>

int main()

    int n;
    while (~scanf("%d", &n)) 
        long long maxa = n;
        for (int i = 2; i <= n; i++) 
            long long t = i;
            while (t != 1) 
                if (t % 2 == 0) t /= 2;
                else t = t * 3 + 1;
                maxa = t > maxa ? t : maxa;
            
        

        printf("%lld\\n", maxa);
    

    return 0;

以上是关于LQ0052 冰雹数枚举+角谷猜想的主要内容,如果未能解决你的问题,请参考以下文章

角谷猜想,C语言,输出过程

考拉兹猜想,

P5727 冰雹猜想

用Perl语言编写冰雹猜想程序

P5727 深基5.例3冰雹猜想

Python实现Collatz序列(考拉兹猜想)