遊戲的規則很簡單:恰好移動一根火柴,使等式成立。如下面的等式可以變成3+6=9(還有其他解):移動哪一根火柴能使等式成立?
請你寫一個程式,找出所有的規範解。所謂規範是指:
* 只能改變數字,不能改變符號;
* 數字和符號的組成方式必須嚴格的和圖示的一樣(減號由一根火柴組成);
* 新等式必須形如a+b=c或a-b=c,其中a、b、c都是不含前置0的非負整數。
當然,最重要的是:新的等式必須在數學上成立。
實現代碼:
import java.io.BufferedReader;<br />import java.io.InputStreamReader;<br />import java.util.ArrayList;<br />import java.util.List;</p><p>public class MoveMatch {<br /> /* _ _ _ _ _<br /> * | |<br /> * | 5 |<br /> * | 2 7 |<br /> * | 4 |<br /> * |_ _ _ _ _| 火柴對應的位置<br /> * | |<br /> * | |<br /> * | 1 6 |<br /> * | 3 |<br /> * |_ _ _ _ _|<br /> *<br /> *<br /> * _ _ _ _ _<br /> * |<br /> * 5(1) |<br /> * 2(0) 7(1)|<br /> * 4(1 ) |<br /> * _ _ _ _ _| 01011101<br /> * |<br /> * |<br /> * | 1(1) 6(0)<br /> * | 3(1)<br /> * |_ _ _ _ _<br /> * 標識位 1位 2位 3位 4 位 5位 6位 7位<br /> */<br /> // 所有數字和運算子用八位0和1表示,沒8位中首位為0表示數字,首位是1表示操作符,<br /> // 對於數字對應火柴位置如,如果火柴存在則對應的二進位位為1,否則為0.通過移動1和0來實現移動火柴<br />String[] allNumbers = { "01110111",// 0<br />"00000011",// 1<br />"01011101",// 2<br />"00011111",// 3<br />"00101011",// 4<br />"00111110",// 5<br />"01111110",// 6<br />"00000111",// 7<br />"01111111",// 8<br />"00111111",// 9<br />};<br />String[] operator = { "11000000",// +<br />"10000000",// -<br />"11100000",// =<br />};<br />String[] operatorChar = { "+",// +<br />"-",// -<br />"=",// =<br />};</p><p>// 判斷8為二進位字串是否表示數字<br />public boolean isDigit(String s) {</p><p>if (s.startsWith("0")) {<br />for (int i = 0; i < allNumbers.length; i++) {<br />if (s.equals(allNumbers[i])) {<br />return true;<br />}<br />}<br />}<br />return false;<br />}</p><p>// 判斷8為二進位字串是否表示運算子號<br />public boolean isOperator(String s) {<br />return s.startsWith("1");<br />}</p><p>// 8為二進位字串轉為數字<br />public int translate2Digit(String s) {<br />try {<br />if (isDigit(s)) {<br />for (int i = 0; i < allNumbers.length; i++) {<br />if (s.equals(allNumbers[i])) {<br />return i;</p><p>}<br />}<br />} else {<br />throw new NumberFormatException();<br />}</p><p>} catch (Exception e) {<br />e.printStackTrace();<br />}</p><p>return -1;</p><p>}</p><p>// 8為二進位字串轉為字元<br />public String translate2operator(String s) {<br />try {<br />if (isOperator(s)) {<br />for (int i = 0; i < operator.length; i++) {<br />if (s.equals(operator[i])) {<br />return operatorChar[i];</p><p>}<br />}<br />} else {<br />throw new IsNotOperatorException();<br />}</p><p>} catch (Exception e) {<br />e.printStackTrace();<br />}</p><p>return "";</p><p>}</p><p>// 判斷某個數字對應index位置上的火柴是否可以移動<br />public boolean isMoveable(String s, int index) {<br />if (!isDigit(s))<br />return false;<br />String temp = s.intern();<br />char c = temp.charAt(index);<br />if (c == '1') {<br />temp = temp.substring(0, index) + "0" + temp.substring(index + 1);<br />return isDigit(temp);<br />}<br />return false;<br />}</p><p>// 判斷某個數位位置上受否可以接受一根火柴<br />public boolean isAcceptable(String s, int index) {<br />if (!isDigit(s))<br />return false;<br />String temp = s.intern();<br />char c = temp.charAt(index);<br />if (c == '0') {<br />temp = temp.substring(0, index) + "1" + temp.substring(index + 1);<br />return isDigit(temp);<br />}<br />return false;<br />}</p><p>// 半段某個數字是否可以把indx位上的火柴移動到indexto上<br />public boolean isSelfAcceptable(String s, int index, int indexto) {<br />if (!isDigit(s))<br />return false;<br />String temp = s.intern();<br />char c = temp.charAt(index);<br />char c2 = temp.charAt(indexto);<br />if (c == '1') {<br />temp = temp.substring(0, index) + "0" + temp.substring(index + 1);<br />if (c2 == '0') {<br />temp = temp.substring(0, indexto) + "1"<br />+ temp.substring(indexto + 1);<br />return isDigit(temp);<br />}<br />}</p><p>return false;<br />}</p><p>public void calculate(String string) {<br />int result = -1;<br />int length = string.length();<br />int count = length / 8;<br />// 迴圈移動可以移動的火柴<br />for (int i = 0; i < count; i++) {<br />String source = string.substring(i * 8, (i + 1) * 8);<br />if (isDigit(source)) {<br />// 迴圈所有火柴位移動火柴<br />for (int j = 1; j < 8; j++) {<br />// 判斷j位上的火柴是否可以移動<br />if (isMoveable(source, j)) {<br />// 迴圈多有可以接受火柴的數<br />for (int k = 0; k < count; k++) {<br />String target = string<br />.substring(k * 8, (k + 1) * 8);<br />// 判斷是否為數字<br />if (isDigit(target)) {<br />// 接受火柴和移動火柴是否同時在同一個數字上<br />if (k == i) {<br />// 迴圈所有的火柴位<br />for (int l = 1; l < 8; l++) {<br />// 是否可以接受<br />if (l != j<br />&& isSelfAcceptable(target, j,<br />l)) {<br />String temp = string.intern();<br />int indexMove = i * 8 + j;<br />int indexto = k * 8 + j;<br />// 產生新的字串<br />temp = temp.substring(0, indexMove)<br />+ "0"<br />+ temp<br />.substring(indexMove + 1);<br />temp = temp.substring(0, indexto)<br />+ "1"<br />+ temp<br />.substring(indexto + 1);<br />if (print(temp) == 0)<br />result = 0;</p><p>}<br />}<br />} else {<br />// 迴圈所有的火柴位<br />for (int l = 1; l < 8; l++) {<br />// 判斷時候可以接受火柴<br />if (isAcceptable(target, l)) {<br />String temp = string.intern();<br />int indexMove = i * 8 + j;<br />int indexto = k * 8 + l;<br />// 產生新的結果<br />temp = temp.substring(0, indexMove)<br />+ "0"<br />+ temp<br />.substring(indexMove + 1);<br />temp = temp.substring(0, indexto)<br />+ "1"<br />+ temp<br />.substring(indexto + 1);<br />if (print(temp) == 0)<br />result = 0;<br />}<br />}</p><p>}<br />}</p><p>}</p><p>}<br />}<br />}</p><p>}<br />if (result == -1)<br />System.out.println(-1);<br />}</p><p>@SuppressWarnings("serial")<br />class IsNotOperatorException extends Exception {<br />}</p><p>// 列印結果<br />@SuppressWarnings("unchecked")<br />public int print(String s) {<br />List list = new ArrayList();<br />int length = s.length();<br />int count = length / 8;<br />long result = 0;<br />@SuppressWarnings("unused")<br />long param = 0;<br />String digits = "";<br />String opreator = "";<br />String tempOperator = "";<br />// 產生計算運算式<br />for (int i = 0; i < count; i++) {<br />String source = s.substring(i * 8, (i + 1) * 8);<br />if (isDigit(source)) {<br />digits += translate2Digit(source);<br />// 把運算元排入佇列</p><p>if (!opreator.equals("")) {<br />list.add(new String(opreator));<br />}<br />opreator = "";</p><p>} else {</p><p>if (digits.length() > 0 && digits.startsWith("0")) {<br />return -1;<br />}<br />// 計算結果<br />if (tempOperator.equals("")) {<br />result = Long.valueOf(digits).longValue();<br />}<br />if (tempOperator.endsWith("+")) {<br />result += Long.valueOf(digits).longValue();<br />}<br />if (tempOperator.endsWith("-")) {<br />result -= Long.valueOf(digits).longValue();<br />}<br />opreator = translate2operator(source);<br />tempOperator = opreator;<br />list.add(new String(digits));<br />digits = "";<br />}<br />}<br />list.add(digits);<br />if (digits.length() > 0 && digits.startsWith("0")) {<br />return -1;<br />}</p><p>if (result == Long.valueOf(digits).longValue()) {<br />// 輸出運算式<br />for (int i = 0; i < list.size(); i++) {<br />System.out.print(list.get(i));</p><p>}<br />System.out.println();<br />return 0;<br />}<br />return -1;<br />}</p><p>public static void main(String[] args) throws Exception {<br />MoveMatch test = new MoveMatch();<br />BufferedReader br = new BufferedReader(new InputStreamReader(System.in));<br />String str = null;<br />System.out.println("Enter your value:");<br />str = br.readLine();<br />StringBuffer sb = new StringBuffer(800);<br />for (int i = 0; i < str.length(); i++) {<br />char c = str.charAt(i);<br />if (Character.isDigit(c)) {<br />sb.append(test.allNumbers[Integer.valueOf(c + "").intValue()]);<br />} else {<br />if (c == '+') {<br />sb.append(test.operator[0]);<br />} else if (c == '-') {<br />sb.append(test.operator[1]);<br />} else if (c == '=') {<br />sb.append(test.operator[2]);<br />} else {<br />throw new Exception();<br />}<br />}</p><p>}<br />test.calculate(sb.toString());<br />}<br />}<br />
輸入:9+5=9
輸出:3+5=8
3+6=9