算法趣题-Q21

算法趣题-Q21,第1张

一、问题描述

二、问题分析

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

三、代码实现 1.C/C++实现
#include 

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 
#include 

using namespace std;

typedef unsigned int u_int;

const u_int MAX_BITS = 30;

typedef struct UnsignedBigInt{
	vector 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())

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1325723.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-12
下一篇 2022-06-12

发表评论

登录后才能评论

评论列表(0条)

保存