zoukankan      html  css  js  c++  java
  • Valid Sudoku&&Sudoku Solver

    Valid Sudoku

    Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules.

    The Sudoku board could be partially filled, where empty cells are filled with the character '.'.


    A partially filled sudoku which is valid.

    Note:
    A valid Sudoku board (partially filled) is not necessarily solvable. Only the filled cells need to be validated.

    暴力解法,一行一行的看,一列一列的看,一个一个方格的看,

    代码如下:

    class Solution {
      public:
          bool isValidCell(vector<vector<char> > &board, int a, int b) {
              vector<bool> flag(9, false);
              int idx;
              for (int i = 0; i < 3; ++i) {
                  for (int j = 0; j < 3; ++j) {
                      idx = board[a + i][b + j] - '0';
                      if (idx > 0 && idx <= 9 && !flag[idx])  
                         flag[idx] = true;
                     else if (idx > 0 && idx <= 9 && flag[idx])
                         return false;
                 }
             }
             return true;
         }
         
         bool isValidRow(vector<vector<char> > &board, int a) {
             vector<bool> flag(9, false);
             int idx;
             for (int j = 0; j < 9; ++j) {
                 idx = board[a][j] - '0';
                 if (idx > 0 && idx <= 9 && !flag[idx])  
                     flag[idx] = true;
                 else if (idx > 0 && idx <= 9 && flag[idx])
                     return false;
             }
             return true;
         }
         
          bool isValidCol(vector<vector<char> > &board, int b) {
             vector<bool> flag(9, false);
             int idx;
             for (int i = 0; i < 9; ++i) {
                 idx = board[i][b] - '0';
                 if (idx > 0 && idx <= 9 && !flag[idx])  
                     flag[idx] = true;
                 else if (idx > 0 && idx <= 9 && flag[idx])
                     return false;
             }
             return true;
         }
         
              bool isValidSudoku(vector<vector<char> > &board) {
             for (int i = 0; i < 3; ++i) {
                 for (int j = 0; j < 3; ++j) {
                     if (!isValidCell(board, 3 * i, 3 * j)) 
                         return false;
                 }
             }
             for (int i = 0; i < 9; ++i) {
                 if (!isValidRow(board, i))
                     return false;
             }
             for (int j = 0; j < 9; ++j) {
                 if (!isValidCol(board, j))
                     return false;
             }
             return true;
         }
     };

    一种简介的解法(还没认真看,可能牵扯到一些数学):

    class Solution {
      public:
        bool isValidSudoku(vector<vector<char> > &board) {
            vector<vector<bool>> rows(9, vector<bool>(9,false));  
            vector<vector<bool>> cols(9, vector<bool>(9,false));  
            vector<vector<bool>> blocks(9, vector<bool>(9,false));  
      
            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';  
                    if(rows[i][num] || cols[j][num] || blocks[i - i%3 + j/3][num])  
                        return false;  
                    rows[i][num] = cols[j][num] = blocks[i - i%3 + j/3][num] = true;  
                }  
            return true;  
         }
     };

    Sudoku Solver

    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.


    A sudoku puzzle...


    ...and its solution numbers marked in red.

    很多题乍一看很难,是因为思路不清晰,只要思路清晰了,还是很简单的。

    思路:

    首先,每一行每一列的数字不能重合,其次把81个格子分成9个小格子,每一个格子里面的数字不能重合。

    转:http://www.cnblogs.com/ganganloveu/p/3828401.html

    这题跟N-Queens是一个套路,回溯法尝试所有解。

    需要注意的区别是:

    本题找到解的处理是return true,因此返回值为bool

    N-Queen找到解的处理是保存解,因此返回值为void

    对于每个空位'.',遍历1~9,check合理之后往下一个位置递归。

    由于这里路径尝试本质上是有序的,即1~9逐个尝试,因此无需额外设置状态位记录已经尝试过的方向。

    注意:只有正确达到最终81位置(即成功填充)的填充结果才可以返回,若不然,将会得到错误的填充。

    因此辅助函数solve需要设为bool而不是void

    class Solution {
    public:
        void solveSudoku(vector<vector<char> > &board) {
            solve(board, 0);
        }
        bool solve(vector<vector<char> > &board, int position)
        {
            if(position == 81)
                return true;
    
            int row = position / 9;
            int col = position % 9;
            if(board[row][col] == '.')
            {
                for(int i = 1; i <= 9; i ++)
                {//try each digit
                    board[row][col] = i + '0';
                    if(check(board, position))
                        if(solve(board, position + 1))
                        //only return valid filling
                            return true;
                    board[row][col] = '.';
                }
            }
            else
            {
                if(solve(board, position + 1))
                //only return valid filling
                    return true;
            }
            return false;
        }
        bool check(vector<vector<char> > &board, int position)
        {
            int row = position / 9;
            int col = position % 9;
            int gid;
            if(row >= 0 && row <= 2)
            {
                if(col >= 0 && col <= 2)
                    gid = 0;
                else if(col >= 3 && col <= 5)
                    gid = 1;
                else
                    gid = 2;
            }
            else if(row >= 3 && row <= 5)
            {
                if(col >= 0 && col <= 2)
                    gid = 3;
                else if(col >= 3 && col <= 5)
                    gid = 4;
                else
                    gid = 5;
            }
            else
            {
                if(col >= 0 && col <= 2)
                    gid = 6;
                else if(col >= 3 && col <= 5)
                    gid = 7;
                else
                    gid = 8;
            }
    
            //check row, col, subgrid
            for(int i = 0; i < 9; i ++)
            {
                //check row
                if(i != col && board[row][i] == board[row][col])
                    return false;
                
                //check col
                if(i != row && board[i][col] == board[row][col])
                    return false;
                
                //check subgrid
                int r = gid/3*3+i/3;
                int c = gid%3*3+i%3;
                if((r != row || c != col) && board[r][c] == board[row][col])
                    return false;
            }
            return true;
        }
    };

      

  • 相关阅读:
    as3的InteractivePNG例子
    HttpWebRequest模拟POST提交防止中文乱码
    net发布的dll方法和类显示注释信息(字段说明信息)[图解]
    IP地址、手机归属和身份证查询接口
    一些好用的开源控件
    c# 操作IIS应用程序池
    c# 获取电脑硬件信息通用查询类[测试通过]
    C# 操作线程的通用类[测试通过]
    几款浏览器JavaScript调试工具
    Microsoft SQL Server 2005 提供了一些工具来监控数据库
  • 原文地址:https://www.cnblogs.com/qiaozhoulin/p/4778002.html
Copyright © 2011-2022 走看看