Sudoku---暴搜解题

本文介绍了一种利用深度优先搜索算法解决九宫格填数问题的方法,通过检查行、列以及3x3小格内的数字出现情况,避免重复数字并确定可填数字。
摘要由CSDN通过智能技术生成

题目大意 :填空格 使得每一行 每一列 每一个九宫格都有1-9

从(0,0)一直搜,准备一个数组记录一下这一行,这一列,这一个九宫格的数字。

如图,来到(0,1)位置,这一行的数字是1,3,5,9,

 for (int p = 0; p < 9; p++)
 {
     if (map[i][p])cnt_numb[map[i][p]]++;//L-R
 }

这一列的数字是6.

 for (int p = 0; p < 9; p++)
 {
     if (map[p][j])cnt_numb[map[p][j]]++;//U-D
 }

这个九宫格数字是1,2,3.

//搜3*3方格
for (int p = i / 3 * 3; p < i / 3 * 3 + 3; p++)
{
    for (int l = j / 3 * 3; l < j / 3 * 3 + 3; l++)
    {
        cnt_numb[map[p][l]]++;
    }
}

所以这个空格不能填1,2,3,5,6,9.可以填的数字是4,7,8。然后开始下一个格子的搜索。

dfs(i,j)表示当前是第i行第j列 每次搜索 j++(从左到右) j到边界后 i++ j=0

 如果j和i都到达边界 输出结果

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
using namespace std;
int map[10][10];
int flag = 0;
void dfs(int i, int j)
{
    if (flag)
        return;
    if (j > 8)
    {
        i++;
        j = 0;
        if (i > 8)
        {
            flag = 1;
            for (int s = 0; s < 9; s++)
            {
                for (int u = 0; u < 9; u++)
                {
                    cout << map[s][u];
                }cout << "\n";
            }
        }
    }

    //
    if (map[i][j] == 0)//填
    {
        int cnt_numb[100];
        memset(cnt_numb, 0, sizeof(cnt_numb));

        /*
        * 1 2 3 4 5
        * 2 0 4 5 1
        * 0 0 0 0 0
        * 0 0 0 0 0
        * 0 0 0 0 0
        */

        for (int p = 0; p < 9; p++)
        {
            if (map[i][p])cnt_numb[map[i][p]]++;//L-R
        }
        for (int p = 0; p < 9; p++)
        {
            if (map[p][j])cnt_numb[map[p][j]]++;//U-D
        }
        //搜3*3方格
        for (int p = i / 3 * 3; p < i / 3 * 3 + 3; p++)
        {
            for (int l = j / 3 * 3; l < j / 3 * 3 + 3; l++)
            {
                cnt_numb[map[p][l]]++;
            }
        }

        for (int q = 1; q <= 9; q++)
        {
            if (!cnt_numb[q])//0
            {
                map[i][j] = q;
                dfs(i, j + 1);
                map[i][j] = 0;
            }
        }
    }
    else
    {
        dfs(i, j + 1);
    }return;

}
int main()
{
    //行确定 L-R 
    //列确定 U-D
    int t;
    cin >> t;
    char ch;
    while (t--)
    {
        memset(map, 0, sizeof(map));
        flag = 0;
        for (int m = 0; m < 9; m++)
        {
            for (int n = 0; n < 9; n++)
            {
                cin >> ch;
                map[m][n] = ch - '0';
            }
        }
        dfs(0, 0);//0行 0列
    }
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值