`
ftj20003
  • 浏览: 133480 次
  • 性别: Icon_minigender_1
  • 来自: ...
社区版块
存档分类
最新评论

一道位操作的趣味编程题

    博客分类:
  • Java
阅读更多
    看到一道很有意思的编程题:大厅里有64盏灯,每盏灯都编了号码,分别为1-64。每盏灯都由一个开关来控制。(开关按一下,灯亮,再按一下灯灭。开关的编号与被控制的灯相同。)开始时,灯是全灭的。现在按照以下规则按动开关。 第一次,将所有的灯点亮。 第二次,将所有2的倍数的开关按一下。 第三次,将所有3 的倍数的开关按一下。以此类推。第N次,将所有N的倍数的开关按一下。 问第N次(N小于等于64)按完以后,大厅里还有几盏灯是亮的。提示可以用long型数字去做,很巧妙刚刚好表示64位,0或者1代表打开或者关闭。写了个实现和原作者的基本思路是一样的:
/**
 * 
 * @author: yanxuxin
 * @date: 2010-3-13
 */
public class LightSwiter {

	public static void main(String[] args) {
		long lights = switchLights(3);
		convert2Binary(lights);
		System.out.println();
		countOpenedLights(lights);
	}

	/**
	 * 切换开关
	 * 
	 * @param sequence
	 * @return
	 */
	public static long switchLights(int sequence) {
		long lights = 0l; //所有的都是关闭的状态,即64位均为0
		for (int i = 1; i <= sequence; i++) {
			for (int j = 1; j <= 64; j++) {

				if (j % i == 0) {  //符合第n次的倍数
					long temp = 1l; 
					temp = temp << (j - 1); //准备截取当前位

					if ((lights & temp) == 0) { //表明lights的当前位为0,即关闭状态
						lights = lights | temp; //不影响其他位数的情况下,改变lights的当前位的状态为1
					}
					else {
						temp = ~temp;
						lights = lights & temp; //不影响其他位数的情况下,改变lights的当前位的状态为0
					}
				}
			}
		}
		return lights;
	}

	/**
	 * 统计点亮的灯数
	 * 
	 * @param lights
	 */
	public static void countOpenedLights(long lights) {
		int remains = 0;
		for (int k = 0; k < 64; k++) {
			long temp = 1l;
			temp = temp << k;
			temp = (lights & temp); //截取当前位判断
			if (temp != 0) {
				remains++;
				System.out.println("The " + (k + 1) + " light is opened.");
			}
		}
		System.out.println("Total " + remains + " lights are opened.");
	}

	/**
	 * 转化成二进制的表达式显示
	 * 
	 * @param number
	 */
	public static void convert2Binary(long number) {
		long res = number / 2;
		long rem = number % 2;
		if (res != 0) {
			convert2Binary(res);
		}
		System.out.print(rem);
	}
}

这个题目解答的巧妙之处就在于使用位操作来变换每一位的状态,非常好的思路。
分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    用C++编写的常见趣味题

    以上只是文件中提及的部分题目,每一道题都蕴含着丰富的算法知识和编程技巧,对于初学者来说是极好的实践机会,对于有一定经验的程序员而言,则是提升技能和拓宽知识面的好途径。通过解决这些趣味题,不仅能加深对...

    c语言原创趣味试题(2)难度比第一次的加大了一些

    【C语言趣味试题解析】 C语言是一门基础且强大的编程语言,它被广泛应用于系统开发、软件编程、嵌入式系统等各个领域。本篇主要介绍三道有趣的C语言试题,涉及数字运算、数据处理及几何计算。 1. **Digital Root ...

    (完整word版)C语言编程练习题绝对经典!.doc

    1. 数学运算: resourceName-"马克思手稿中的一道趣味数学题",该题目要求编写程序,采用穷举法求出结果,解决男人、女人和小孩各有几人的问题。 2. 数学运算: resourceName-"编写程序,根据公式求 e 的值",该...

    (完整版)C语言编程练习题绝对经典!.doc

    * 马克思手稿中有一道趣味数学题:有30个人,其中有男人、女人和小孩,在一家饭馆里吃饭共花了50先令,每个男人各花3先令,每个女人各花2先令,每个小孩各花1先令,问男人、女人和小孩各有几人?可以使用穷举法编写...

    C语言编程练习题绝对经典!(DOC).doc

    马克思手稿中有一道趣味数学题:有 30 个人,其中有男人、女人和小孩,在一家饭馆里吃饭共花了 50 先令,每个男人各花 3 先令,每个女人各花 2 先令,每个小孩各花 1 先令,问男人、女人和小孩各有几人?...

    信息技术中考模拟题

    - **二进制加法**:题目中给出了一道简单的二进制加法题:“二进制数0011+0001=()”。解答这类问题的关键在于理解二进制的基本规则,即每一位只能是0或1,当两个1相加时,会产生一个进位。因此,0011 + 0001 的结果...

    《C++程序设计》课后习题解答(第二版)

    移位法是Stein算法的一种实现,利用位操作减少计算次数,是理解计算机底层运算机制的好例子。 总的来说,《C++程序设计》课后习题解答(第二版)覆盖了C++语言的各个方面,从基础语法到高级特性的应用,是学习者...

    acm选拔赛题目

    解决这类问题通常需要具备扎实的编程基础,包括但不限于数据结构(如集合)、算法(如位操作)以及问题解决策略(如试错法、归纳法)。此外,良好的团队协作能力和时间管理也是ACM竞赛中必不可少的素质,因为比赛中...

    PapersPlease Codewar题解

    "PapersPlease"是其中一道颇有趣味性的算法题,让我们深入探讨它的解决策略。 题目背景: “PapersPlease”这个名字源自一款反乌托邦背景的游戏,这里我们将它转化为一个算法问题。假设你是一名边境检查员,你的...

Global site tag (gtag.js) - Google Analytics