`
jiajw0426
  • 浏览: 24934 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

用java解决百度之星移动火柴的问题

阅读更多

在百度,同事们之间喜欢交流游戏。其中,火柴游戏是一个比较经典的例子。游戏的规则很简单:恰好移动一根火柴,使等式成立。如下面的等式可以变成3+6=9(还有其他解):移动哪一根火柴能使等式成立?

 


请你写一个程序,找出所有的规范解。所谓规范是指:
    * 只能改变数字,不能改变符号;
    * 数字和符号的组成方式必须严格的和图示的一样(减号由一根火柴组成);
    * 新等式必须形如a+b=c或a-b=c,其中a、b、c都是不含前导0的非负整数。
当然,最重要的是:新的等式必须在数学上成立。

 

 

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class MoveMatch {
	/*     _ _ _ _ _ 
	 *    |         |
	 *    |    5    |   
	 *    | 2     7 | 
	 *    |    4    |
	 *    |_ _ _ _ _|        火柴对应的位置
	 *    |         |
	 *    |         |   
	 *    | 1     6 | 
	 *    |    3    |
	 *    |_ _ _ _ _| 
	 *    
	 *    
	 *     _ _ _ _ _ 
	 *              |
	 *        5(1)  |   
	 *     2(0) 7(1)| 
	 *        4(1 ) |
	 *     _ _ _ _ _|        0    1     0   1   1   1   0   1
	 *    |          
	 *    |                标识位    1位     2位    3位    4位    5位   6位    7位  
	 *    | 1(1) 6(0)  
	 *    |    3(1)     
	 *    |_ _ _ _ _  
	 * 
	 */
		//所有数字和运算符用八位0和1表示,没8位中首位为0表示数字,首位是1表示操作符,
		//对于数字对应火柴位置如上图,如果火柴存在则对应的二进制位为1,否则为0.通过移动1和0来实现移动火柴
	String[] allNumbers = { 
			"01110111",// 0
			"00000011",// 1
			"01011101",// 2
			"00011111",// 3
			"00101011",// 4
			"00111110",// 5
			"01111110",// 6
			"00000111",// 7
			"01111111",// 8
			"00111111",// 9
	};
	String[] operator = { 
			"11000000",// +
			"10000000",// -
			"11100000",// =
	};
	String[] operatorChar = { "+",// +
			"-",// -
			"=",// =
	};
   
	//判断8为二进制字符串是否表示数字
	public boolean isDigit(String s) {
		
		if (s.startsWith("0")) {
			for (int i = 0; i < allNumbers.length; i++) {
				if (s.equals(allNumbers[i])) {
					return true;
				}
			}
		}
		return false;
	}
	//判断8为二进制字符串是否表示运算符号
	public boolean isOperator(String s) {
		return s.startsWith("1");
	}
    //8为二进制字符串转为数字
	public int translate2Digit(String s) {
		try {
			if (isDigit(s)) {
				for (int i = 0; i < allNumbers.length; i++) {
					if (s.equals(allNumbers[i])) {
						return i;

					}
				}
			} else {
				throw new NumberFormatException();
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

		return -1;

	}
	//8为二进制字符串转为字符
	public String translate2operator(String s) {
		try {
			if (isOperator(s)) {
				for (int i = 0; i < operator.length; i++) {
					if (s.equals(operator[i])) {
						return operatorChar[i];

					}
				}
			} else {
				throw new IsNotOperatorException();
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

		return "";

	}
    //判断某个数字对应index位置上的火柴是否可以移动
	public boolean isMoveable(String s, int index) {
		if (!isDigit(s))
			return false;
		String temp = s.intern();
		char c = temp.charAt(index);
		if (c == '1') {
			temp = temp.substring(0, index) + "0" + temp.substring(index + 1);
			return isDigit(temp);
		}
		return false;
	}
   //判断某个数字的位置上受否可以接受一根火柴
	public boolean isAcceptable(String s, int index) {
		if (!isDigit(s))
			return false;
		String temp = s.intern();
		char c = temp.charAt(index);
		if (c == '0') {
			temp = temp.substring(0, index) + "1" + temp.substring(index + 1);
			return isDigit(temp);
		}
		return false;
	}
   //半段某个数字是否可以把indx位上的火柴移动到indexto上
	public boolean isSelfAcceptable(String s, int index, int indexto) {
		if (!isDigit(s))
			return false;
		String temp = s.intern();
		char c = temp.charAt(index);
		char c2 = temp.charAt(indexto);
		if (c == '1') {
			temp = temp.substring(0, index) + "0" + temp.substring(index + 1);
			if (c2 == '0') {
				temp = temp.substring(0, indexto) + "1"
						+ temp.substring(indexto + 1);
				return isDigit(temp);
			}
		}

		return false;
	}

	public void calculate(String string) {
		int result = -1;
		int length = string.length();
		int count = length / 8;
		//循环移动可以移动的火柴
		for (int i = 0; i < count; i++) {
			String source = string.substring(i * 8, (i + 1) * 8);
			if (isDigit(source)) {
				 //循环所有火柴位移动火柴
				for (int j = 1; j < 8; j++) {
					//判断j位上的火柴是否可以移动
					if (isMoveable(source, j)) {
						//循环多有可以接受火柴的数
						for (int k = 0; k < count; k++) {
							String target = string
									.substring(k * 8, (k + 1) * 8);
							//判断是否为数字
							if (isDigit(target)) {
								//接受火柴和移动火柴是否同时在同一个数字上
								if (k == i) {
									//循环所有的火柴位
									for (int l = 1; l < 8; l++) {
										//是否可以接受
										if (l != j
												&& isSelfAcceptable(target, j,
														l)) {
											String temp = string.intern();
											int indexMove = i * 8 + j;
											int indexto = k * 8 + j;
											//生成新的字符串
											temp = temp.substring(0, indexMove)
													+ "0"
													+ temp
															.substring(indexMove + 1);
											temp = temp.substring(0, indexto)
													+ "1"
													+ temp
															.substring(indexto + 1);
											if (print(temp) == 0)
												result = 0;

										}
									}
								} else {
									//循环所有的火柴位
									for (int l = 1; l < 8; l++) {
										//判断时候可以接受火柴
										if (isAcceptable(target, l)) {
											String temp = string.intern();
											int indexMove = i * 8 + j;
											int indexto = k * 8 + l;
											//生成新的结果
											temp = temp.substring(0, indexMove)
													+ "0"
													+ temp
															.substring(indexMove + 1);
											temp = temp.substring(0, indexto)
													+ "1"
													+ temp
															.substring(indexto + 1);
											if (print(temp) == 0)
												result = 0;
										}
									}

								}
							}

						}

					}
				}
			}

		}
		if (result == -1)
			System.out.println(-1);
	}

	class IsNotOperatorException extends Exception {

	}
 //打印结果 
	public int print(String s) {
		List list = new ArrayList();
		int length = s.length();
		int count = length / 8;
		long result = 0;
		long param = 0;
		String digits = "";
		String opreator = "";
		String tempOperator = "";
		//生成计算表达式
		for (int i = 0; i < count; i++) {
			String source = s.substring(i * 8, (i + 1) * 8);
			if (isDigit(source)) {
				digits += translate2Digit(source);
				//把操作数加入队列
				
				if(!opreator.equals("")){
				list.add(new String(opreator));
				}
				opreator = "";

			} else {
				
				if (digits.length() > 0 && digits.startsWith("0")) {
					return -1;
				}
				//计算结果
				if (tempOperator.equals("")) {
					result = Long.valueOf(digits).longValue();
				}
				if (tempOperator.endsWith("+")) {
					result += Long.valueOf(digits).longValue();
				}
				if (tempOperator.endsWith("-")) {
					result -= Long.valueOf(digits).longValue();
				}
				opreator = translate2operator(source);
				tempOperator = opreator;
				list.add(new String(digits));
				digits = "";
			}
		}
		list.add(digits);
		if (digits.length() > 0 && digits.startsWith("0")) {
			return -1;
		}

		if (result == Long.valueOf(digits).longValue()) {
			//输出表达式
			for (int i = 0; i < list.size(); i++) {
				System.out.print(list.get(i));

			}
			System.out.println();
			return 0;
		}
		return -1;
	}

	public static void main(String[] args) throws Exception {
		MoveMatch test = new MoveMatch();
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String str = null;
		System.out.println("Enter your value:");
		str = br.readLine();
		StringBuffer sb = new StringBuffer(800);
		for (int i = 0; i < str.length(); i++) {
			char c = str.charAt(i);
			if (Character.isDigit(c)) {

				sb.append(test.allNumbers[Integer.valueOf(c + "").intValue()]);
			} else {
				if (c == '+') {
					sb.append(test.operator[0]);
				} else if (c == '-') {
					sb.append(test.operator[1]);
				} else if (c == '=') {
					sb.append(test.operator[2]);
				} else {
					throw new Exception();
				}
			}

		}
		test.calculate(sb.toString());
      
	}
}

 

 

 

分享到:
评论
2 楼 gmizr 2009-06-09  
这么多层if,for嵌套,很吓人啊
1 楼 jellyfish 2009-06-09  
my comment:

http://jellyfish.iteye.com/admin/blogs/404622

相关推荐

    java 拿火柴游戏

    Java 拿火柴游戏实验报告 一、 程序功能介绍 拿火柴游戏是一种与计算机相互对拿火柴的游戏程序,旨在训练人脑的逻辑思维能力。游戏的玩法是用系统产生的随机函数产生火柴数量(大约在 20—50 之间),每次每一方...

    java火柴游戏设计

    《Java火柴游戏设计》 火柴游戏是一种经典的智力游戏,通常由两个...这个过程不仅可以提升编程技能,也能锻炼逻辑思维和问题解决能力。无论你是初学者还是有一定经验的开发者,这样的课程设计都能提供宝贵的实践机会。

    用java编写的火柴游戏

    首先,游戏的核心是使用Java的`Math.random()`函数来生成随机的火柴数量。`Math.random()`函数返回一个0.0到1.0之间的随机浮点数,通过乘以(50-20)并加上20,可以得到20到50之间的随机整数,代表火柴堆的初始数量。...

    java课程设计-拿火柴游戏

    Java课程设计是一个重要的实践环节,旨在让学生通过实际编程项目来巩固和深化理论知识。在这个“拿火柴游戏”项目中,我们将深入...通过这个项目,学生不仅可以加深对Java语言的理解,还能提高实际编程和问题解决能力。

    移动火柴游戏

    在这款基于C++Builder开发的小游戏中,玩家需要通过移动火柴棍来解决一系列的谜题,目标是达到预设的目标形状或数字组合。游戏的核心在于观察、分析和创新,激发玩家的空间想象能力和逻辑推理能力。 C++Builder是一...

    JAVA拿火柴小游戏

    JAVA拿火柴的小游戏,使用JDK编写,JAVA初学者的范例程序,有出错循环,

    用JAVA设计的火柴游戏

    次程序是用JAVA编写的火柴游戏。电脑有一定的智能。

    移动一根火柴使等式成立js版本

    这种类型的问题不仅考验逻辑思维能力,还能培养解决问题的能力。 ### 实现思路 该程序的主要实现思路可以概括为以下几点: 1. **定义数字变化规则**:首先定义了每个数字在添加、移动或减少一根火柴棍后可能变成的...

    小学一年级下奥数专题—移火柴棒-一年级火柴棍.docx

    通过这样的练习,孩子们不仅可以提升数学技能,还能培养解决问题的策略和耐心,这对于他们的学习成长至关重要。在教学过程中,家长和老师可以鼓励孩子多尝试,多思考,激发他们对数学的兴趣,培养他们的创新思维。

    移动一根火柴令等式成立(递归)

    ### 移动一根火柴令等式成立(递归)详解 #### 一、问题背景与目标 在解决“移动一根火柴令等式成立”的...这种方法不仅能够处理简单的等式变换,还能够应对更复杂的情况,为解决问题提供了一种灵活而强大的工具。

    人机拿火柴游戏java代码

    人机对拿火柴的游戏程序 游戏过程要显示火柴总数 选择谁先拿

    java小程序 数火柴游戏 图形界面

    这是一个使用Java Swing框架开发的简单数火柴游戏。游戏的目标是通过移除一定数量的火柴来击败对手。游戏采用图形用户界面(GUI),使得玩家能够直观地看到当前游戏的状态,并进行操作。 ### 二、主要类和组件介绍 #...

    巧移火柴棒练习题 (二年级)-二年级数学小棒题.docx

    巧移火柴棒是一种经典的数学智力游戏,适合于低年级学生锻炼思维灵活性和逻辑推理能力。...通过这些题目,孩子们能够更好地理解数字的结构、运算规则以及图形的变化规律,同时培养了解决问题的策略和技巧。

    巧移火柴棒练习题集(二年级)~二年级数学小棒题.doc

    巧移火柴棒是一种锻炼逻辑思维和数学技巧的趣味题型,主要针对低年级学生,旨在提高他们的数学理解和创新思维。...通过解决这类问题,孩子们不仅可以提升数学技能,还能培养解决问题的策略和思维方式。

    基于JAVA实现的控制台火柴棍游戏

    Match-game ,字如其名,乃是火柴棍游戏,其实现的功能是输入最大位数、操作火柴滚数量以及操作类型,自动生成一个通过对火柴棍操作(移动、增加、删除)形成等式的游戏。 本项目是Java应用技术 课程的平时作业,...

    JAVA课程设计合集!!!大学课程。贪吃蛇,21点,火柴人,俄罗斯方块,拼图游戏等多款课程设计游戏!

    Java课程设计是大学计算机科学教育中的重要组成部分,它旨在帮助学生深入理解面向对象编程思想,增强实际编程能力和软件...如果你在使用过程中遇到任何问题,记得寻求帮助,共同探讨和解决问题是学习过程中的重要环节。

    还记得:移动其中一根火柴使等式成立的趣味游戏吗?

    1. **谜题生成**:程序需要能随机生成或预定义一系列的火柴等式,这些等式需要有至少一种解决方案,即通过移动一根火柴使等式成立。 2. **图形界面**:Unity3D的图形渲染能力可以创建逼真的3D火柴模型,用户可以...

    巧移火柴棒教学设计.docx

    6.思考题:通过移动火柴棒,学生可以学习解决问题的方法和策略。 四、教学目标 * 培养学生动手能力和空间想象能力 * 通过火柴棒摆出数字图形和巧移火柴棒等活动,提高学生的逻辑思维和问题解决能力 * 培养学生的...

    巧移火柴棒游戏训练方法及训练题库.docx

    本篇文章将详细介绍巧移火柴棒游戏的训练方法,并深入探讨训练题库的运用,旨在帮助玩家在娱乐中提高他们的思维灵活性和解决问题的技巧。 ### 巧移火柴棒游戏的训练方法 #### 第一阶段:入门练习 初学者首先需要...

    移动火柴棍

    用C语言写的算法,四位数火柴棍移动其中一根变四位最大数。

Global site tag (gtag.js) - Google Analytics