poj2676 Sudoku 数独

本文介绍了一种使用深度优先搜索(DFS)算法解决数独问题的方法,通过记录空位置和利用哈希表进行判断,提高了搜索效率。该方法特别强调了从后向前搜索的重要性,相较于正向搜索,其时间复杂度更低。

记录所有空位置,三个数组(row[M][M], col[M][M], mat[3][3][M])hash判断当前空位置是否可以填某个数,然后直接DFS,注意从后往前搜索,时间比正向搜快很多。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

#define M 11

struct point { int x, y; } p[100];
//row[i][j]表示第i行是否有数字j,col[i][j]表示第i列是否有数字j,mat[i][j][k]表示第(i,j)位置的小九宫格里是否有数字k
int map[M][M];
bool flag, row[M][M], col[M][M], mat[3][3][M];
int np;

void DFS(int num)
{
    if (flag) return;

    int i, j;

    if (num == -1) {
        for (i = 0; i < 9 && !flag; i++) {
            for (j = 0; j < 9; j++)
                printf ("%d", map[i][j]);
            printf ("\n");
        }
        flag = true;
        return;
    }

    for (i = 1; i <= 9 && !flag; i++) {
        int x = p[num].x;
        int y = p[num].y;
        if (!row[x][i] && !col[y][i] && !mat[x/3][y/3][i]) {
            row[x][i] = col[y][i] = mat[x/3][y/3][i] = true;
            map[x][y] = i;
            DFS(num-1);
            row[x][i] = col[y][i] = mat[x/3][y/3][i] = false;
            map[x][y] = 0;
        }
    }
}

int main()
{
    int t, i, j;

    scanf ("%d", &t);
    while (t--) {
        memset (row, false, sizeof (row));
        memset (col, false, sizeof (col));
        memset (mat, false, sizeof (mat));
        np = 0;
        for (i = 0; i < 9; i++) {
            for (j = 0; j < 9; j++) {
                scanf ("%1d", &map[i][j]);
                int num = map[i][j];
                if (num)
                    row[i][num] = col[j][num] = mat[i/3][j/3][num] = true;
                else {
                    p[np].x = i;
                    p[np++].y = j;
                }
            }
        }
        flag = false;
        DFS(np-1);
    }
    return 0;
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值