关闭 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 |
    ——–┼———┼———┤

    上一篇返回首页 下一篇

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

    别人在看

    Destoon 模板存放规则及语法参考

    Destoon系统常量与变量

    Destoon系统目录文件结构说明

    Destoon 系统安装指南

    Destoon会员公司主页模板风格添加方法

    Destoon 二次开发入门

    Microsoft 将于 2026 年 10 月终止对 Windows 11 SE 的支持

    Windows 11 存储感知如何设置?了解Windows 11 存储感知开启的好处

    Windows 11 24H2 更新灾难:系统升级了,SSD固态盘不见了...

    小米路由器买哪款?Miwifi热门路由器型号对比分析

    IT头条

    Synology 对 Office 套件进行重大 AI 更新,增强私有云的生产力和安全性

    01:43

    StorONE 的高效平台将 Storage Guardian 数据中心占用空间减少 80%

    11:03

    年赚千亿的印度能源巨头Nayara 云服务瘫痪,被微软卡了一下脖子

    12:54

    国产6nm GPU新突破!砺算科技官宣:自研TrueGPU架构7月26日发布

    01:57

    公安部:我国在售汽车搭载的“智驾”系统都不具备“自动驾驶”功能

    02:03

    技术热点

    最全面的前端开发指南

    Windows7任务栏桌面下角的一些正在运行的图标不见了

    sql server快速删除记录方法

    SQL Server 7移动数据的6种方法

    SQL Server 2008的新压缩特性

    每个Java程序员必须知道的5个JVM命令行标志

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

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