[C++] PAT(Basic Level)1001 害死人不偿命的(3n+1)猜想 (15 分)

卡拉兹(Callatz)猜想:

对任何一个正整数 n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把 (3n+1) 砍掉一半。这样一直反复砍下去,最后一定在某一步得到 n=1。卡拉兹在 1950 年的世界数学家大会上公布了这个猜想,传说当时耶鲁大学师生齐动员,拼命想证明这个貌似很傻很天真的命题,结果闹得学生们无心学业,一心只证 (3n+1),以至于有人说这是一个阴谋,卡拉兹是在蓄意延缓美国数学界教学与科研的进展……

我们今天的题目不是证明卡拉兹猜想,而是对给定的任一不超过 1000 的正整数 n,简单地数一下,需要多少步(砍几下)才能得到 n=1?

输入格式:

每个测试输入包含 1 个测试用例,即给出正整数 n 的值。

输出格式:

输出从 n 计算到 1 需要的步数。

输入样例:

3

输出样例:

5

思考:

这种题就是奇偶判断进行相应的处理并计数,其中关键奇偶判断处理时间开销问题。

  • 奇偶处理:对于一个数值 n 其奇偶性,是用 n%2 进行处理,还是 n&1 来处理;
           取模运算(%):其本质在计算机中还是用二进制数值的“原码除法”,而“原码除法”本质是“原码加法”和“原码减法”,进行多次二进制运算,详细计算过程及原因《计算机组成原理》有讲;
           与运算(&):本质也是二进制运算,但它直接取二进制原码(负数用补码比较)的最后一位和1相与,相同为1,不同为0,只进行一次二进制运算,当然比取模运算快多了(快的飞起)。为什么这样果断?想想看,奇数的二进制码最后一位是不是都是1,偶数的二进制码最后一位都是0!!!
    (可参考本人另一篇博客讲解:https://blog.youkuaiyun.com/C_DreShadow/article/details/83758222
  • 时间开销:除号(/)和移位符号(>>)之间的关系,其中二进制码除法的计算过程不在多说,上面解释有。主要是移位运算,其实就是二进制码整体相右平移移位,你说那个快点,当然是移位运算啦。 

代码:

// PAT_code_test.cpp: 定义控制台应用程序的入口点。
//

#include <iostream>
#include <stdio.h>
using namespace std;

int main()
{
	int n;
	cin >> n;
	int num = 0;
	while (true)
	{
		if (n == 1)break;
		if (n & 1)		// &与运算 直接判断数字最后一个二进制位是否为1
		{
			n = (3 * n + 1) >> 1;
		}
		else
		{
			n = n >> 1;	// >>移位运算 直接将数字的二进制码整体右移移位,高位用0补齐
		}
		++num;
	}
	cout << num << endl;

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值