猜想: 对于任意大于1的自然数n,若n为奇数,则将n变为3n+1,否则变为n的一半。
    经过若干次这样的变换,一定会使n变为1。例如3->10->5->16->8->2->1。
    输入n,输出变换的次数。n≤10^9。
     样例输入:3
     样例输出:7

不假思索的写出下面的代码:

#include<stdio.h>
int main(void)
{
int n;
int count=0; scanf("%d", &n); while(n > 1)
{
if(n%2 != 0)
n = 3*n + 1;
else
n /= 2;
count++;
} printf("%d\n", count); return 0;
}

然而,程序正确吗?很不幸,如果输入987654321,答案为1,这显然是错误的。通过调试或者在循环体中用printf语句打印出n的值,看到n的值为负数,导致一次循环后程序退出。从这里可以获悉n的值溢出了,因为整型最大值为2^31-1 = 2147483647,大约为21亿,而由题意n的最大值为10亿(10^9),所以在n的值颇大且为奇数时乘以3是危险的,会导致溢出。

解决方案如下:

因为奇数*奇数=奇数,所以经过n=3*n+1的计算后,n的值必然是偶数,并且下次循环必然做运算n/=2,所以这里可以合并这两步,也就是n为奇数的情况下做运算n=floor(1.5*n+0.5),由于double值的误差问题,我们可以用n=floor(1.5*n+1)(floor函数接收double类型的参数,返回不大于给定参数的最大整形数,返回值类型为double),将取整后的double值赋给整形从而丢弃小数点。

修改后的程序如下:

#include<stdio.h>
#include<math.h>
int main(void)
{
int n;
int count=0; scanf("%d", &n); while(n > 1)
{
if(n%2 != 0)
{
n = floor(1.5*n + 1);
count += 2;
}
else
{
n = n / 2;
count++;
}
} printf("%d\n", count); return 0;
}

再次用987654321测试,得到结果180次。再者,如果对n的限制为整形int的范围,该程序就不能完成要求了,那么我们可以使用long long int。

参考资料:《算法竞赛入门经典》——刘汝佳

最后一些疑惑(望看到的高手能解答一二,吾将不胜感激):

1、这里第二个程序是我依照作者的提示写的,自认应该正确吧:-),但是还是有一些疑惑,比如我们考虑了第一次n的输入值,但是循环

  中的第二次,第三次...呢?我们如何说明以后循环的值不会发生溢出呢?

  比如开始时n的值为7,那么一次循环后其值为11,而11>7。也就是说二次循环的值大于7。

2、再者,我们如何知道经过若干次的变换后一定会得到1呢,也就是说我们如何知道函数收敛呢?嗯...这貌似是一个数学问题啊。

All Rights Reserved.
Author:海峰:)
Copyright © xp_jiang.
转载请标明出处:http://www.cnblogs.com/xpjiang/p/4129340.html

———————————————————^_^我是更新线2014年12月5日 16:15:21^_^——————————————————

关于这个问题的答案我是在数学科普神犇顾森的博客中找到的,其博客地址在这里Matrix67(顺便推荐,很好的博客呢),原文见这里千万别学数学:最折磨人的数学未解之谜(一),下面把与该问题相关的文字摘录在这里:

数学之美不但体现在漂亮的结论和精妙的证明上,那些尚未解决的数学问题也有让人神魂颠倒的魅力。和 Goldbach 猜想、 Riemann 假设不同,有些悬而未解的问题趣味性很强,“数学性”非常弱,乍看上去并没有触及深刻的数学理论,似乎是一道可以被瞬间秒杀的数学趣题,让数学爱好者们“不找到一个巧解就不爽”;但令人称奇的是,它们的困难程度却不亚于那些著名的数学猜想,这或许比各个领域中艰深的数学难题更折磨人吧。

作为一本数学趣题集, Mathematical Puzzles 一书中竟把仍未解决的数学趣题单独列为一章,可见这些问题有多么令人着迷。我从这一章里挑选了一些问题,在这里和大家分享一下。这本书是 04 年出版的,书里提到的一些“最新进展”其实已经不是最新的了;不过我也没有仔细考察每个问题当前的进展,因此本文的信息并不保证是 100% 准确的,在此向读者们表示歉意。

3x + 1 问题

    从任意一个正整数开始,重复对其进行下面的操作:如果这个数是偶数,把它除以 2 ;如果这个数是奇数,则把它扩大到原来的 3 倍后再加 1 。序列是否最终总会变成 4, 2, 1, 4, 2, 1, … 的循环?

    这个问题可以说是一个“坑”——乍看之下,问题非常简单,突破口很多,于是数学家们纷纷往里面跳;殊不知进去容易出去难,不少数学家到死都没把这个问题搞出来。已经中招的数学家不计其数,这可以从 3x + 1 问题的各种别名看出来: 3x + 1 问题又叫 Collatz 猜想、 Syracuse 问题、 Kakutani 问题、 Hasse 算法、 Ulam 问题等等。后来,由于命名争议太大,干脆让谁都不沾光,直接叫做 3x + 1 问题算了。

    3x + 1 问题不是一般的困难。这里举一个例子来说明数列收敛有多么没规律。从 26 开始算起, 10 步就掉入了“421 陷阱”:

26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1, 4, 2, 1, …

    但是,从 27 开始算起,数字会一路飙升到几千多,你很可能会一度认为它脱离了“421 陷阱”;但是,经过上百步运算后,它还是跌了回来:

27, 82, 41, 124, 62, 31, 94, 47, 142, 71, 214, 107, 322, 161, 484, 242, 121, 364, 182, 91, 274, 137, 412, 206, 103, 310, 155, 466, 233, 700, 350, 175, 526, 263, 790, 395, 1186, 593, 1780, 890, 445, 1336, 668, 334, 167, 502, 251, 754, 377, 1132, 566, 283, 850, 425, 1276, 638, 319, 958, 479, 1438, 719, 2158, 1079, 3238, 1619, 4858, 2429, 7288, 3644, 1822, 911, 2734, 1367, 4102, 2051, 6154, 3077, 9232, 4616, 2308, 1154, 577, 1732, 866, 433, 1300, 650, 325, 976, 488, 244, 122, 61, 184, 92, 46, 23, 70, 35, 106, 53, 160, 80, 40, 20, 10, 5, 16, 8, 4, 2, 1, 4, 2, 1, …

额外的,再说一点:如上所述,既然数列的收敛如此没有规律,那么上面我们的程序可能是错误的(包括优化过后的那个)。举一个例子,我们用 long long int 做一个测试:

#include<math.h>
int main(void)
{
long long int n;
int count=; // 统计计算次数 scanf("%I64d", &n); // long long int在windows下一定要用%I64d读入数据,否则会出问题(比如数据截断什么的)
long long max = ; // 记录计算过程中出现的最大值 while(n > )
{
if(n% != )
{
//n = floor(1.5*n + 1);
n = n * + ;
}
else
{
n = n / ; }
count++;
printf("%I64d\n", n); // 输出也使用%I64d if(n > max)
max = n;
} printf("%d\n%I64d\n", count, max); return ;
}

我们输入704511,最后那个printf函数的输出结果:242,56991483520。可见其中间值有5百亿这么大,而用 n = floor(1.5*n + 1) 语句代替 n = n * 3 + 1;输出的中间值为28495741760,也有2百亿那么大,int类型存不下这么大的数据,所以更新线之前的两个程序在测试强度不够的情况下表面上看是正确,实则是错误的。
最后,写的这里,应该可以告一段落了。

3n+1问题的更多相关文章

  1. - > code vs 3038 3n+1问题(递归)

    3038 3n+1问题  时间限制: 1 s  空间限制: 32000 KB  题目等级 : 白银 Silver 题解   题目描述 Description 3n+1问题是一个简单有趣而又没有解决的数 ...

  2. 害死人不偿命的(3n+1)猜想

    卡拉兹(Callatz)猜想: 对任何一个自然数n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把(3n+1)砍掉一半.这样一直反复砍下去,最后一定在某一步得到n=1.卡拉兹在1950年的世界数 ...

  3. 1001. 害死人不偿命的(3n+1)猜想 (15)

    1001. 害死人不偿命的(3n+1)猜想 (15) 较简单,直接代码实现: #include <cstdio> int main() { int n; scanf("%d&qu ...

  4. PAT 乙级 1005. 继续(3n+1)猜想 (25)

    1005. 继续(3n+1)猜想 (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B   卡拉兹(Callatz)猜想已经在1001中给出了描述.在这个题目里,情 ...

  5. 1293. 3n+1数链问题 2016 12 23

    /* 1293. 3n+1数链问题 Constraints Time Limit: 1 secs, Memory Limit: 32 MB Description 在计算机科学上,有很多类问题是无法解 ...

  6. 3n+1b 备忘录方法

    题目详情 对任何一个自然数n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把(3n+1)砍掉一半.这样一直反复砍下去,最后一定在某一步得到n=1.卡拉兹在1950年的世界数学家大会上公布了这个猜 ...

  7. PAT 1001. 害死人不偿命的(3n+1)猜想 (15)

    卡拉兹(Callatz)猜想: 对任何一个自然数n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把(3n+1)砍掉一半.这样一直反复砍下去,最后一定在某一步得到 n=1.卡拉兹在1950年的世界 ...

  8. UVa 100 - The 3n + 1 problem(函数循环长度)

    题目来源:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=3&pa ...

  9. 烟大 Contest1024 - 《挑战编程》第一章:入门 Problem A: The 3n + 1 problem(水题)

    Problem A: The 3n + 1 problem Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 14  Solved: 6[Submit][St ...

随机推荐

  1. Happy

    1.delighted 2.over the moon                   Alex is over the moon with promotion. 3.really pleased ...

  2. web_custom_request函数详解

    在LR中当使用HTML录制方式时,录制的脚本中主要由函数web_link().web_submit_form().web_url().web_submit_data()组成,当使用HTTP录制方式时, ...

  3. laravel elixir

    npm install npm install jquery --save //bootsrap3.36 与 jquery3不兼容,下载jquery时可能需要确定版本号 npm install jqu ...

  4. ubuntu日志清理

    由于ubuntu日志文件syslog 和 kern.log 时刻在增长,一会儿就使得根目录文件夹不够用了,需使用如下命令清理 sudo -i输入密码echo  > /var/log/syslog ...

  5. 利用sqlserver日志恢复数据

    如果你已经急的焦头烂额,看到这篇文章的时候,请你换个坐姿,深呼吸几次,静下心来将这篇文章读完,也许你的问题迎刃而解. 我遇 到的情况是这样的,网站被植入木马,盗取了我的web.config文件,web ...

  6. php--yii2框架错误提示

    if($code!=200){ $user=new UserAuth(); $user->mobile=$register['mobile']; $user->password=md5($ ...

  7. 一张表有三个字段:id(城市id) Cityname(城市名) Privence(所属省份)如果要统计每个省份有多少城市请用SQL实现。

    一张表有三个字段:id(城市id) Cityname(城市名) Privence(所属省份)如果要统计每个省份有多少城市请用SQL实现.

  8. Asp.net MVC 批量删除数据

    ProductList视图 <div class="mid"> <div id="editInfo"> @using (Html.Beg ...

  9. windows远程桌面连接树莓派

    1.树莓派上需要安装xrdp(An open source remote desktop protocol(rdp) server). sudo apt-get install xrdp 远程桌面打开 ...

  10. spring mvc 静态资源 404问题

    spring mvc 静态资源 404问题 在web.xml配置servlet-mapping的时候,如果url-pattern设置为"/" (如下),很多人都会遇到导入js,cs ...