zoukankan      html  css  js  c++  java
  • Leetcode0037--Sudoku Solver 数独游戏

    【转载请注明】http://www.cnblogs.com/igoslly/p/8719622.html

     

    来看一下题目:

           Write a program to solve a Sudoku puzzle by filling the empty cells.

    Empty cells are indicated by the character '.'.

           You may assume that there will be only one unique solution.

    题目意思:

    完成数独游戏的计算

    在做这题的前两天,楼主正在摸索华为笔试题的时候,已经写了一个非常直白的实现,具体链接如下:

    http://www.cnblogs.com/igoslly/p/8708960.html

    不过和原题有些区别:① 所有数据均以字符串形式保存  ②  需要填写的位置以 “.” 代替 0

    我们稍稍修改下代码,就可以得到实现方法1

    bool check(int n,char key,vector<vector<char>> num){
        for(int i=0;i<9;i++){
            int j=n/9;
            if(num[j][i]==key)
            {
                return false;
            }
        } 
        for(int i=0;i<9;i++)
        {
            int j=n%9;
            if(num[i][j]==key){return false;}
        }
        
        int x=n/9/3*3;
        int y=n%9/3*3;
        for(int i=x;i<x+3;i++){
            for(int j=y;j<y+3;j++){
                if(num[i][j]==key){return false;}
            }
        }
        return true;
    }
    void dfs(int n,vector<vector<char>> &num,bool *sign){
        if(n>80)
        {
            *sign=true;
            return;
        }
        if(num[n/9][n%9]!='.')
        { 
            dfs(n+1,num,sign);
        }else{
            for(char i='1';i<='9';i++)
            {
                if(check(n,i,num)==true){
                    num[n/9][n%9]=i;
                    dfs(n+1,num,sign);
                    if(*sign==true) return;
                }
            }
            num[n/9][n%9]='.';
        }
    }
    class Solution {
    public:
        void solveSudoku(vector<vector<char>>& board) {
            bool sign=false;
            dfs(0,board,&sign);
        }
    };

    实现方法2:

            优化check函数,将原先逐行、逐列遍历进行判断的方法 → 记录每行、每列、每九宫格是否含有当前数字

            具体实施较原先冗长的代码简短太多)

        // line[i][j],column[i][j],subcube[i][j] 分别代表数独每行、每列、每个子单元是否含有数字j(对应1-9)
        bool line[9][9],column[9][9],subcube[9][9];

            进行dfs前,首先要对原题给出的数字进行记录

    // 将所有数组置为false
            memset(line,false,sizeof(line));
            memset(column,false,sizeof(column));
            memset(subcube,false,sizeof(subcube));
            // 根据题意,设定初始数组的值
            for(int i=0;i<9;i++){
                for(int j=0;j<9;j++){
                    if(board[i][j]=='.')
                        continue;
                    
                    int num=board[i][j]-'1';
                    // 给定题目存在问题,无解,直接返回
                    int cube=i/3*3 + j/3;
                    if(line[i][num] || column[j][num] || subcube[cube][num])   
                        return ;
                    line[i][num] = column[j][num] = subcube[cube][num] = true;
                }
            }

    实现方法3:

          在实现方法1中,我们使用 n = 0~80 来记录当前填充空格,根据 n 是否越界判断数独填充是否完成。

          当然我们也可以采用 i & j / row & col 对位置进行记录,更为直观;

          逐行进行填充时,需要对 j > 8 (初始 0)进行换行操作:

    // 当j>8时,i++,否则 i 值不变
    // 当j>8时,及时取余,重新从0~8计算
    (i,j)  -> (i+(j+1)/9,(j+1)%9)

           具体递归代码:

        bool step(vector<vector<char>>&board,int i,int j){
            if(i==9)
                return true;
            if(board[i][j]!='.')
            {
                if(i==8&&j==8){
                    return true;
                }
                else{
                    return step(board,i+(j+1)/9,(j+1)%9);   // step里值表示i,j换行
                }
            }
             
            int cube=i/3*3 + j/3;
            for(int k=0;k<9;k++){
                if(line[i][k] || column[j][k] || subcube[cube][k])
                    continue;
                line[i][k] = column[j][k] = subcube[cube][k] = true;
                board[i][j] = '1'+k;
    
                if(step(board,i+(j+1)/9,(j+1)%9))    // 若数独已完成,直接返回true
                    return true;
                line[i][k] = column[j][k] = subcube[cube][k] = false;
                board[i][j] = '.';
            }
            return false;
        }
  • 相关阅读:
    Unique Encryption Keys 暴力学习map,vector 函数
    hdu 1250 Hat's Fibonacci
    匈牙利算法模板 图的二分匹配 hdu 2063 过山车
    hdu 4260 汉诺塔问题 The End of The World
    各种常见文件的hex文件头
    Ubuntu & node.js
    Linux周期性任务的执行指令配置
    MySQL各版本的性能特性(从4.0版本开始)
    Tsung 1.5.0 增加对 WebSocket 和 BOSH 的支持
    ShowSlow+Yslow环境搭建
  • 原文地址:https://www.cnblogs.com/igoslly/p/8719622.html
Copyright © 2011-2022 走看看