关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » JAVA »Java解世界最难九宫格问题

    Java解世界最难九宫格问题

    2015-01-13 00:00:00 出处:技术小黑屋
    分享

    芬兰数学家因卡拉花费3个月设计出了世界上迄今难度最大的数独游戏,而且它只有一个答案。因卡拉说只有思考能力最快、头脑最聪明的人才能破解这个游戏。

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

    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() + " | "); 
                    else 
                        System.out.print(numMat[i][j].getValue() + "  "); 
                } 
                if ((i + 1) % 3 == 0) 
                    System.out.println("rn--------┼---------┼---------┤"); 
                else 
                    System.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 |
    ——–┼———┼———┤

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    Edge浏览器百度被劫持/篡改怎么办,地址后边跟着尾巴#tn=68018901_7_oem_dg

    Google Chrome 在 iPhone 上新增了 Safari 数据导入选项

    Windows 11专业版 KMS工具激活产品密钥的方法

    DEDECMS安全策略官方出品

    Microsoft Text Input Application 可以关闭吗?

    新版本QQ如何关闭自带的浏览器?

    C++编程语言中continue的用法和功能,附举例示范代码

    c++ map 的数据结构、基本操作以及其在实际应用中的使用。

    C语言如何避免内存泄漏、缓冲区溢出、空指针解引用等常见的安全问题

    C语言中的break语句详解

    IT头条

    马斯克2026最新采访总结:2040年,全球机器人数量将突破100亿台

    23:52

    专家解读|规范人工智能前沿业态健康发展的新探索:解读《人工智能拟人化互动服务管理暂行办法》

    00:54

    用至强 6高存力搞定MoE卸载!

    17:53

    美国将允许英伟达向中国“经批准的客户”出售H200 GPU

    02:08

    苹果与微信就15%手续费达成一致?腾讯未置可否

    22:00

    技术热点

    PHP 和 Node.js 的10项对比挑战

    Javascript闭包深入解析及实现方法

    windows 7、windows 8.1手动增加右键菜单功能技巧

    MYSQL出错代码大汇总

    windows 7假死机怎么办 windows 7系统假死机的原因以及解决方法

    Ubuntu(Linux)下配置IP地址的方法

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。