在百度,同事们之间喜欢交流游戏。其中,火柴游戏是一个比较经典的例子。游戏的规则很简单:恰好移动一根火柴,使等式成立。如下面的等式可以变成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());
}
}
分享到:
- 2009-06-01 15:08
- 浏览 1153
- 评论(2)
- 论坛回复 / 浏览 (2 / 5721)
- 查看更多
相关推荐
Java 拿火柴游戏实验报告 一、 程序功能介绍 拿火柴游戏是一种与计算机相互对拿火柴的游戏程序,旨在训练人脑的逻辑思维能力。游戏的玩法是用系统产生的随机函数产生火柴数量(大约在 20—50 之间),每次每一方...
《Java火柴游戏设计》 火柴游戏是一种经典的智力游戏,通常由两个...这个过程不仅可以提升编程技能,也能锻炼逻辑思维和问题解决能力。无论你是初学者还是有一定经验的开发者,这样的课程设计都能提供宝贵的实践机会。
首先,游戏的核心是使用Java的`Math.random()`函数来生成随机的火柴数量。`Math.random()`函数返回一个0.0到1.0之间的随机浮点数,通过乘以(50-20)并加上20,可以得到20到50之间的随机整数,代表火柴堆的初始数量。...
Java课程设计是一个重要的实践环节,旨在让学生通过实际编程项目来巩固和深化理论知识。在这个“拿火柴游戏”项目中,我们将深入...通过这个项目,学生不仅可以加深对Java语言的理解,还能提高实际编程和问题解决能力。
在这款基于C++Builder开发的小游戏中,玩家需要通过移动火柴棍来解决一系列的谜题,目标是达到预设的目标形状或数字组合。游戏的核心在于观察、分析和创新,激发玩家的空间想象能力和逻辑推理能力。 C++Builder是一...
JAVA拿火柴的小游戏,使用JDK编写,JAVA初学者的范例程序,有出错循环,
次程序是用JAVA编写的火柴游戏。电脑有一定的智能。
这种类型的问题不仅考验逻辑思维能力,还能培养解决问题的能力。 ### 实现思路 该程序的主要实现思路可以概括为以下几点: 1. **定义数字变化规则**:首先定义了每个数字在添加、移动或减少一根火柴棍后可能变成的...
通过这样的练习,孩子们不仅可以提升数学技能,还能培养解决问题的策略和耐心,这对于他们的学习成长至关重要。在教学过程中,家长和老师可以鼓励孩子多尝试,多思考,激发他们对数学的兴趣,培养他们的创新思维。
### 移动一根火柴令等式成立(递归)详解 #### 一、问题背景与目标 在解决“移动一根火柴令等式成立”的...这种方法不仅能够处理简单的等式变换,还能够应对更复杂的情况,为解决问题提供了一种灵活而强大的工具。
人机对拿火柴的游戏程序 游戏过程要显示火柴总数 选择谁先拿
这是一个使用Java Swing框架开发的简单数火柴游戏。游戏的目标是通过移除一定数量的火柴来击败对手。游戏采用图形用户界面(GUI),使得玩家能够直观地看到当前游戏的状态,并进行操作。 ### 二、主要类和组件介绍 #...
巧移火柴棒是一种经典的数学智力游戏,适合于低年级学生锻炼思维灵活性和逻辑推理能力。...通过这些题目,孩子们能够更好地理解数字的结构、运算规则以及图形的变化规律,同时培养了解决问题的策略和技巧。
巧移火柴棒是一种锻炼逻辑思维和数学技巧的趣味题型,主要针对低年级学生,旨在提高他们的数学理解和创新思维。...通过解决这类问题,孩子们不仅可以提升数学技能,还能培养解决问题的策略和思维方式。
Match-game ,字如其名,乃是火柴棍游戏,其实现的功能是输入最大位数、操作火柴滚数量以及操作类型,自动生成一个通过对火柴棍操作(移动、增加、删除)形成等式的游戏。 本项目是Java应用技术 课程的平时作业,...
Java课程设计是大学计算机科学教育中的重要组成部分,它旨在帮助学生深入理解面向对象编程思想,增强实际编程能力和软件...如果你在使用过程中遇到任何问题,记得寻求帮助,共同探讨和解决问题是学习过程中的重要环节。
1. **谜题生成**:程序需要能随机生成或预定义一系列的火柴等式,这些等式需要有至少一种解决方案,即通过移动一根火柴使等式成立。 2. **图形界面**:Unity3D的图形渲染能力可以创建逼真的3D火柴模型,用户可以...
6.思考题:通过移动火柴棒,学生可以学习解决问题的方法和策略。 四、教学目标 * 培养学生动手能力和空间想象能力 * 通过火柴棒摆出数字图形和巧移火柴棒等活动,提高学生的逻辑思维和问题解决能力 * 培养学生的...
本篇文章将详细介绍巧移火柴棒游戏的训练方法,并深入探讨训练题库的运用,旨在帮助玩家在娱乐中提高他们的思维灵活性和解决问题的技巧。 ### 巧移火柴棒游戏的训练方法 #### 第一阶段:入门练习 初学者首先需要...
用C语言写的算法,四位数火柴棍移动其中一根变四位最大数。