深度搜索之数独

编写一个程序,通过已填充的空格来解决数独问题。

一个数独的解法需遵循如下规则:

数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
空白格用 '.' 表示。

        采用深度搜索的方式,如果非空格就需要进行n+1收拾,如果搜索成功则采用book数组标记,shuo搜索失败需要回退对数独的修改,具体的实现见代码。

#include<iostream>
#include<string>
#include<vector>
#include<memory.h>
using namespace::std;

class Solution {
public:
    void solveSudoku(vector<vector<char>>& board) {
        int row_len = board.size();
        int col_len = board[0].size();
        cout<<row_len<<" "<<col_len<<endl;

        bool *book = (bool *)malloc(row_len * col_len * sizeof(bool));
        memset(book, 0, row_len * col_len*sizeof(bool));
        
        DFS(board, book, 0);
        Output(board);
        free(book);
    }
    void Output(vector<vector<char>>& board)
    {
        for(auto str: board)
        {
            for(auto c: str)
            {
                cout<<c<<' ';
            }
            cout<<endl;
        }
    }
    bool checkNumOk(vector<vector<char>>& board, int n, const char key)
    {
        bool bRet = false;
        int row_len = board.size();
        int col_len = board[0].size();
        /* 判断n所在的行是否合法 */
        for(int j = 0; j < col_len; j++)
        {
            int i = n / col_len;
            if(board[i][j] == key)
            {
                return bRet;
            }

        }
        /* 判断n所在的列是否合法 */
        for(int i = 0; i < row_len; i++)
        {
            int j = n % col_len;
            if(board[i][j] == key)
            {
                return bRet;
            }
        }
       
        /* x为n所在的小九宫格左顶点竖坐标 */
	    int x = n / 9 / 3 * 3;
	    /* y为n所在的小九宫格左顶点横坐标 */
	    int y = n % 9 / 3 * 3;
 
        /* 判断n所在的小九宫格是否合法 */
        for (int i = x; i < x + 3; i++)
        {
            for (int j = y; j < y + 3; j++)
            {
                if (board[i][j] == key)
                {
                    return bRet;
                }
            }
        }

        return true;
    }

    bool DFS(vector<vector<char>>& board, bool *book , int n)
    {
        int row_len = board.size();
        int col_len = board[0].size();
        if (n >= row_len * col_len)
        {
            return true;
        }
        
        if(board[n / col_len][n % col_len] != '.')
        {
            book[n] = true;
            if(DFS(board, book, n + 1))
            {
                return true;
            }
        }
        else
        {
            for(int i = 0; i < 9; i++)
            {
                char ch = i + '1';
                if(checkNumOk(board, n, ch) && !book[n])
                {
                    board[n / col_len][n % col_len] = ch;
                    Output(board);
                    cout<<endl;
                    book[n] = true;
                    if(DFS(board, book, n + 1))
                    {
                        return true;
                    }

                    /* 如果构造不成功,还原当前位 */
                    board[n / col_len][n % col_len] = '.';
                    book[n] = false;
                }
            }
        }

        return false;
    }
};

int main()
{
    vector<vector<char> > board = {
        {'5',  '3',  '.',  '.',  '7',  '.',  '.',  '.',  '.'},
        {'6',  '.',  '.',  '1',  '9',  '5',  '.',  '.',  '.'},
        {'.',  '9',  '8',  '.',  '.',  '.',  '.',  '6',  '.'},
        {'8',  '.',  '.',  '.',  '6',  '.',  '.',  '.',  '3'},
        {'4',  '.',  '.',  '8',  '.',  '3',  '.',  '.',  '1'},
        {'7',  '.',  '.',  '.',  '2',  '.',  '.',  '.',  '6'},
        {'.',  '6',  '.',  '.',  '.',  '.',  '2',  '8',  '.'},
        {'.',  '.',  '.',  '4',  '1',  '9',  '.',  '.',  '5'},
        {'.',  '.',  '.',  '.',  '8',  '.',  '.',  '7',  '9'}
        };
        
        Solution abj;
        abj.solveSudoku(board);

        return 0;
}

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值