算法趣题-Q21

一、问题描述

二、问题分析

        本题可以直接进行模拟解题,如代码实现中的Python实现,而书中提到另一种模拟方式,只需要使用一个大整数进行迭代,代码思路如C++实现第一部分,下一层的数为当前层的数与当前层数左移一位异或的结果,由于最后结果为75,超出了C++存储容量,这里代码仅供参考;C++第二部分为根据C++会溢出的结果进行的代码编写,通过vector进行一个大数的实现,以达到求解的目的。

三、代码实现

1.C/C++实现

#include <iostream>

using namespace std;

int count_zero(unsigned long long num)
{
	int num_zero = 0;
	while (num)
	{
		if ((num & 1) == 0)
			num_zero++;
		num >>= 1;
	}
	return num_zero;
}

int main()
{
	unsigned long long cur = 1;
	int level = 1, zero = 0;
	// 由于最后结果为 75 层,超过了C++的存储能力,代码运行会产生错误结果
	// 此代码仅提供思路
	while (zero < 1024)
	{
		cur ^= (cur << 1);
		level++;
		zero += count_zero(cur);
	}
	cout << level << endl;
	return 0;
}
#include <iostream>
#include <vector>

using namespace std;

typedef unsigned int u_int;

const u_int MAX_BITS = 30;

typedef struct UnsignedBigInt{
	vector<u_int> val;
	static const u_int MAX_NUM = 1 << MAX_BITS;
} UB_Int;

void left_shift(UB_Int& num)
{
	// 将 num 左移 bits 位
	u_int carry = 0;
	for (size_t i = 0; i < num.val.size(); i++)
	{
		// 当前域左移
		num.val[i] <<= 1;
		num.val[i] += carry;

		// 计算是否有进位,并修正当前域值
		carry = num.val[i] / num.MAX_NUM;
		num.val[i] %= num.MAX_NUM;
	}
	// 判断是否需要新的域
	if (carry)
		num.val.push_back(carry);
}

void get_next(UB_Int& cur)
{
	UB_Int last = cur;
	left_shift(cur);
	for (size_t i = 0; i < last.val.size(); i++)
		cur.val[i] ^= last.val[i];
}

int count_zero(const UB_Int& num)
{
	int num_of_zero = 0;

	for (size_t i = 0; i < num.val.size() - 1; i++)
	{
		// 计算域中的 0 的数目
		int tmp = num.val[i];
		for (size_t j = 0; j < MAX_BITS; j++)
		{
			if ((tmp & 1) == 0)
				num_of_zero++;
			tmp >>= 1;
		}
	}

	// 最后一个计算 0 的数目不同
	int tmp = num.val.back(); 
	while (tmp)
	{
		if ((tmp & 1) == 0)
			num_of_zero++;
		tmp >>= 1;
	}

	return num_of_zero;
}

int main()
{
	UB_Int cur;
	cur.val.push_back(1);
	u_int level = 1;

	for (int zero = 0; zero < 2014; zero += count_zero(cur))
	{
		get_next(cur);
		level++;
	}

	cout << level << endl;

	return 0;
}

 

2.Python实现

# coding=utf-8


def simulate():
    last = [1, 1]
    level = 2
    count = 0
    while count < 2014:
        # 生成下一层
        cur = [1, ]
        for i in range(len(last) - 1):
            t = last[i] ^ last[i + 1]  # 异或的值
            if t == 0:
                count += 1
            cur.append(t)
        cur.append(1)

        # 更新当前层
        last = cur
        level += 1

    return level


if __name__ == '__main__':
    print(simulate())

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值