基于java的九宫格求解程序。以荷兰数学家设计的世界最难九宫格为例。

来源:互联网 发布:手游防御矩阵攻略 编辑:程序博客网 时间:2024/04/30 02:46

今日,一则腾讯的新闻称中国老头三天破解世界最难九宫格,虽然最后老人是改了一个数字,但是引起本人一时兴趣,想通过计算机程序求解该问题,于是在宿舍呆了一下午,终于成功求解,程序源码如下。

package numberGame;public class Point {private int col;// 行号private int row;// 列号private boolean flag;// 真为未设置。private int value;// 构造点public Point(int col, int row, boolean flag, int value) {super();this.col = col;this.row = row;this.flag = flag;this.value = value;}public void changeFlag() {flag = !flag;}public boolean getFlag() {return flag;}public int getValue() {return value;}public void setValue(int value) {this.value = value;}public boolean canHere(Point[][] pArr) {boolean cb = canCol(pArr);boolean cr = canRow(pArr);boolean cminiArr = canMiniArr(pArr);return cb && cr && cminiArr;}//判断在小3*3格子里是否有相同元素private boolean canMiniArr(Point[][] pArr) {int coltemp = this.col % 3;int rowtemp = this.row % 3;for (int i = this.col - coltemp; i < col + (3 - coltemp); i++) {for (int j = this.row - rowtemp; j < row + (3 - rowtemp); j++) {if(i == this.col && j == this.row){continue;}else{if(this.value == pArr[i][j].getValue()){return false;}}}}return true;}// 判断列上是否有相同元素private boolean canRow(Point[][] pArr) {for (int i = 0; i < 9; i++) {if (i == this.col) {continue;} else {if (this.value == pArr[i][this.row].value) {// 行变,列不变return false;}}}return true;}// 判断行上是否有相同元素private boolean canCol(Point[][] pArr) {for (int i = 0; i < 9; i++) {if (i == this.row) {continue;} else {if (this.value == pArr[this.col][i].value) {// 列边,行不变return false;}}}return true;}}


------主程序--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

package numberGame;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.ArrayList;public class Number99 {public static void main(String[] args) throws IOException{Point[][] numMat = new Point[9][9];ArrayList<Point> al = new ArrayList<Point>();initNumMat(numMat,al);setNum(numMat,al);printMat(numMat);}private static void setNum(Point[][] numMat,ArrayList<Point> al) {int i = 0;int j = 0;do{if (numMat[i][j].getFlag()) {for (int v = numMat[i][j].getValue()+1; v <= 9; v++) {//给回退到的位置的值加一。numMat[i][j].setValue(v);if (numMat[i][j].canHere(numMat)) {//满足条件,不冲突。numMat[i][j].changeFlag();//改变标记为假。表示已设置过。break;}else{//满足不条件,冲突。value值自加一次}while(v == 9){//如果1-9都不能满足要求,则先将本位重置为0,并回退一格,给回退到的位置的值加一(当回退位置的值不为9时,并且保证回退到的位置不是九宫格原本的点)。numMat[i][j].setValue(0);j--;if(j==-1){i--;j=8;}while(al.contains(numMat[i][j])){//如果回退到的位置为九宫格本来的点时,继续回退,直到不是本身的点时跳出while。j--;if(j==-1){i--;j=8;}}numMat[i][j].changeFlag();//将标记v = numMat[i][j].getValue();}}}j++;if(j==9){j=0;i++;//此处i++ 可能使i自加为9,故下面需要i!=9判断}if(i!=9){while(al.contains(numMat[i][j])){j++;if(j==9){j=0;i++;}}}}while(i!=9);}public static void initNumMat(Point[][] numMat,ArrayList<Point> al) throws IOException {for (int i = 0; i < numMat.length; i++) {for (int j = 0; j < numMat[i].length; j++) {numMat[i][j] = new Point(i, j, true, 0);}}initNumMat2(numMat, al);}public static void initNumMat2(Point[][] numMat, ArrayList<Point> al) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));String[] p = new String[3];String line=null;System.out.println("请按格式输入点信息(i行号, j列号 v值),输入结束输入over: i j v ");while((line = br.readLine())!=null){if(line.equals("over"))break;p = line.trim().split(" +");numMat[Integer.parseInt(p[0])][Integer.parseInt(p[1])].setValue(Integer.parseInt(p[2]));numMat[Integer.parseInt(p[0])][Integer.parseInt(p[1])].changeFlag();al.add(numMat[Integer.parseInt(p[0])][Integer.parseInt(p[1])]);}}public static void printMat(Point[][] numMat) {System.out.println("--------┬---------┬---------┐");for (int i = 0; i < numMat.length; i++) {for (int j = 0; j < numMat[i].length; j++) {if ((j + 1) % 3 == 0)System.out.print(numMat[i][j].getValue() + " | ");elseSystem.out.print(numMat[i][j].getValue() + "  ");}if ((i + 1) % 3 == 0)System.out.println("\r\n--------┼---------┼---------┤");elseSystem.out.println();}}}


 

运行程序----------------------------------------------------

请按格式输入点信息(i行号, j列号 v值),输入结束输入over: i j v
0 0 8
1 2 3
1 3 6
2 1 7
2 4 9
2 6 2
3 1 5
3 5 7
4 4 4
4 5 5
4 6 7
5 3 1
5 7 3
6 2 1
6 7 6
6 8 8
7 2 8
7 3 5
7 7 1
8 1 9
8 6 4
over
--------┬---------┬---------┐
8  1  2 | 7  5  3 | 6  4  9 |
9  4  3 | 6  8  2 | 1  7  5 |
6  7  5 | 4  9  1 | 2  8  3 |
--------┼---------┼---------┤
1  5  4 | 2  3  7 | 8  9  6 |
3  6  9 | 8  4  5 | 7  2  1 |
2  8  7 | 1  6  9 | 5  3  4 |
--------┼---------┼---------┤
5  2  1 | 9  7  4 | 3  6  8 |
4  3  8 | 5  2  6 | 9  1  7 |
7  9  6 | 3  1  8 | 4  5  2 |
--------┼---------┼---------┤

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 月经期间卫生巾搞得屁股疼怎么办 大姨妈特别多用卫生巾老是漏怎么办 夏天用卫生巾不透气摩擦红了怎么办 在日本的洗手间用完的姨妈巾怎么办 想穿短裙但是膝盖怕凉怎么办 裤子被卫生巾粘住扯不下来怎么办 医生说来姨妈不可以用卫生巾怎么办 隆胸以后摸起来感觉假体会动怎么办 产后15个月说恶露没排干净怎么办 母猪产后两天肚子里还有小猪怎么办 背心式无痕运动文胸显得胸小怎么办 卫生巾过敏起疙瘩反复挠不好怎么办 去健身房办卡老板跑了怎么办 买货我已经拒收商家不退款怎么办 在京东买了东西拒收不退款怎么办 罗马仕充电宝进入休眠状态怎么办 广发信用卡寄到家没拿到快递怎么办 包邮商家要买家出物流费怎么办? 美团外卖下单转化率低怎么办 京东退款不小心点了取消退款怎么办 近邻宝开了箱又关了怎么办 近邻宝箱子打开了东西忘记拿怎么办 京东取消订单商家总不取消怎么办 京东快递退货取件一直取不到怎么办 在京东线上付款了但没收到货怎么办 寄快递收件人电话号码写错了怎么办 京东购物实名认证被别人占用怎么办 货已发出单号还没填买家退货怎么办 自提柜还有一个包忘记拿怎么办 当顾客说衣服太贵的时候怎么办 京东快递送错了被别人签收了怎么办 乐视1s玩王者荣耀卡怎么办 京东商城买东西发现地址错了怎么办 京东分期付款买手机额度不够怎么办 亮皮银色高跟鞋时间放久变色怎么办 饿了么商家钱包提现被锁了怎么办 在淘手游买的游戏账号被找回怎么办 交易猫买手游梦幻号被找回了怎么办 绑定着苹果账号的邮箱忘记了怎么办 京东注册账号跟密码都忘记了怎么办 孩子大学一个宿舍宿友不行怎么办