• java实现拉丁方块填数字


    “数独”是当下炙手可热的智力游戏。一般认为它的起源是“拉丁方块”,是大数学家欧拉于1783年发明的。

    如图[1.jpg]所示:6x6的小格被分为6个部分(图中用不同的颜色区分),每个部分含有6个小格(以下也称为分组)。
    
    开始的时候,某些小格中已经填写了字母(ABCDEF之一)。需要在所有剩下的小格中补填字母。
    
    全部填好后,必须满足如下约束:
    
    1. 所填字母只允许是A,B,C,D,E,F 中的某一个。
    
    2. 每行的6个小格中,所填写的字母不能重复。
    
    3. 每列的6个小格中,所填写的字母不能重复。
    
    4. 每个分组(参见图中不同颜色表示)包含的6个小格中,所填写的字母不能重复。
    
    为了表示上的方便,我们用下面的6阶方阵来表示图[1.jpg]对应的分组情况(组号为0~5):
    

    022013
    243333
    445555

    用下面的数据表示其已有字母的填写情况:
    

    02C
    03B
    05A
    20D
    35E
    53F

    很明显,第一列表示行号,第二列表示列号,第三列表示填写的字母。行号、列号都从0开始计算。
    
    一种可行的填写方案(此题刚好答案唯一)为:
    

    E F C B D A
    A C E D F B
    D A B E C F
    F B D C A E
    B D F A E C
    C E A F B D

    你的任务是:编写程序,对一般的拉丁方块问题求解,如果多解,要求找到所有解。
    

    【输入、输出格式要求】

    用户首先输入6行数据,表示拉丁方块的分组情况。

    接着用户输入一个整数n (n<36), 表示接下来的数据行数

    接着输入n行数据,每行表示一个预先填写的字母。

    程序则输出所有可能的解(各个解间的顺序不重要)。
    每个解占用7行。

    即,先输出一个整数,表示该解的序号(从1开始),接着输出一个6x6的字母方阵,表示该解。

    解的字母之间用空格分开。

    如果找不到任何满足条件的解,则输出“无解”

    例如:用户输入:
    

    022013
    243333
    445555
    02C
    03B
    05A
    20D
    35E
    53F

    则程序输出:
    

    E F C B D A
    A C E D F B
    D A B E C F
    F B D C A E
    B D F A E C
    C E A F B D

    再如,用户输入:
    002113
    022443
    555553
    04B
    05A
    13D
    14C
    24E
    50C
    51A
    则程序输出:
    D C E F B A
    E F A D C B
    A B F C E D
    B E D A F C
    F D C B A E
    C A B E D F
    D C E F B A
    E F A D C B
    A D F B E C
    B E C A F D
    F B D C A E
    C A B E D F
    D C F E B A
    A E B D C F
    F D A C E B
    B F E A D C
    E B C F A D
    C A D B F E
    D C F E B A
    B E A D C F
    A D C F E B
    F B E A D C
    E F B C A D
    C A D B F E
    D C F E B A
    E F A D C B
    A B C F E D
    B E D A F C
    F D B C A E
    C A E B D F
    D C F E B A
    E F A D C B
    A B D F E C
    B E C A F D
    F D B C A E
    C A E B D F
    D C F E B A
    E F A D C B
    A D B F E C
    B E C A F D
    F B D C A E
    C A E B D F
    D C F E B A
    F E A D C B
    A D B C E F
    B F E A D C
    E B C F A D
    C A D B F E
    D C F E B A
    F E A D C B
    A F C B E D
    B D E A F C
    E B D C A F
    C A B F D E

    package com.liu.ex9;
    
    import java.util.HashSet;
    import java.util.Scanner;
    
    public class Main {
        public static int[][] group = new int[6][6];   //输入分组情况
        public static char[][] result = new char[6][6];  //满足题意的填充结果
        public static int[][] row = new int[6][6];  //检测6行是否均为不同字母
        public static int[][] col = new int[6][6];  //检测6列是否均为不同字母
        public static int[][] set = new int[6][6];  //检测0~5组是否均为不同字母
        public static char[] value = {'A','B','C','D','E','F'};  //填充字母
        public static int count = 0;   //统计最终解个数
        public HashSet<String> hash = new HashSet<String>();
        
        public boolean check() {
            StringBuilder temp = new StringBuilder("");
            for(int i = 0;i < 6;i++) {
                for(int j = 0;j < 6;j++) 
                    temp.append(result[i][j]+" ");
                  temp.append("
    ");
            }
            String A = temp.toString();
            if(hash.contains(A))
                return false;
            return true;
        }
        
        public void dfs(int step) {
            if(step >= 37) {
                if(check()) {  //检测是否有重复解
                    count++;
                    System.out.println(count);
                    StringBuilder temp = new StringBuilder("");
                    for(int i = 0;i < 6;i++) {
                        for(int j = 0;j < 6;j++) 
                            temp.append(result[i][j]+" ");
                          temp.append("
    ");
                    }
                    hash.add(temp.toString());
                    System.out.print(temp);
                }
                return;
            } else {
                int tempRow = (step - 1) / 6;
                int tempCol = (step - 1) % 6;
                int tempSet = group[tempRow][tempCol];
                for(int i = 0;i < 6;i++) {
                    if(result[tempRow][tempCol] == '-') {
                        char temp = (char) ('A' + i);
                        if(row[tempRow][i] == 0 && col[tempCol][i] == 0 && set[tempSet][i] == 0) {
                            result[tempRow][tempCol] = temp;
                            row[tempRow][i] = 1;
                            col[tempCol][i] = 1;
                            set[tempSet][i] = 1;
                            dfs(step + 1);
                            result[tempRow][tempCol] = '-';  //回溯处理
                            row[tempRow][i] = 0;
                            col[tempCol][i] = 0;
                            set[tempSet][i] = 0;
                            
                        } else {
                            continue;
                        }
                    } else {
                        dfs(step + 1);
                    }
                }
            }
            return;
        }
        
        
        public static void main(String[] args) {
            Main test = new Main();
            for(int i = 0;i < 6;i++)
                for(int j = 0;j < 6;j++)
                    result[i][j] = '-';  //初始化为填充格子字符为'-'
            Scanner in = new Scanner(System.in);
            for(int i = 0;i < 6;i++) {
                String temp = in.nextLine();
                for(int j = 0;j < 6;j++)
                    group[i][j] = temp.charAt(j) - '0';
            }
            int n = in.nextInt();
            in.nextLine();
            for(int i = 0;i < n;i++) {
                String temp = in.nextLine();
                int a = temp.charAt(0) - '0';
                int b = temp.charAt(1) - '0';
                int v = temp.charAt(2) - 'A';
                result[a][b] = temp.charAt(2);
                row[a][v] = 1;    //表示第a行位于第v个的位置,已经填充
                col[b][v] = 1;    //表示第b列位于第v个的位置,已经填充
                int tempSet = group[a][b];   //获取(a,b)小组组号
                set[tempSet][v] = 1;   //表示第tempSet小组第v个位置,已经填充
            }
            test.dfs(1);
        }
    }
    
  • 相关阅读:
    geoserver发布地图服务WMTS
    geoserver发布地图服务WMS
    geoserver安装部署步骤
    arcgis api 3.x for js 入门开发系列十四最近设施点路径分析(附源码下载)
    arcgis api 3.x for js 入门开发系列十三地图最短路径分析(附源码下载)
    cesium 之自定义气泡窗口 infoWindow 后续优化篇(附源码下载)
    arcgis api 3.x for js 入门开发系列十二地图打印GP服务(附源码下载)
    arcgis api 3.x for js 入门开发系列十一地图统计图(附源码下载)
    arcgis api 3.x for js 入门开发系列十叠加 SHP 图层(附源码下载)
    arcgis api 3.x for js入门开发系列九热力图效果(附源码下载)
  • 原文地址:https://www.cnblogs.com/a1439775520/p/13077843.html
Copyright © 2020-2023  润新知