POJ2676 Sudoku(dfs)

题目链接

题目大意:

就是数独游戏。横竖,每一个9宫方块,必须有1~9,且不重复。

分析:

直接DFS。一开始在原图上搜,会TLE。把要补全的空格,放入数组,这样就不用遍历整个图寻找要填的空格了。

row, col, sq分别标记行,列,3*3方格是否重复。

话说,直接做

有人说反着搜(正着搜的意思就是从0~cnt-1,反着搜就是从cnt~0),试了试。

AC代码如下:

#include <cstdio>
#include <iostream>
#include <map>
#include <cstring>

using namespace std;

struct node {
    int x, y;
}q[9*9+10];

bool row[10][10], col[10][10], sq[4][4][10];
int G[10][10], cnt;

bool dfs(int cn) {
    if(cn < 0) return true;

    int x = q[cn].x, y = q[cn].y;

    for(int k=1; k<=9; k++) {
        if(row[x][k] || col[y][k] || sq[x/3][y/3][k]) continue;
        row[x][k] = col[y][k] = sq[x/3][y/3][k] = true;

        G[x][y] = k;
        if(dfs(cn-1)) return true;

        row[x][k] = col[y][k] = sq[x/3][y/3][k] = false;
    }

    return false;
}


int main() {
    int T;
    scanf("%d", &T);

    while(T--) {
        cnt = 0;
        memset(row, false, sizeof(row));
        memset(col, false, sizeof(col));
        memset(sq, false, sizeof(sq));

        for(int i=0; i<9; i++) {
            for(int j=0; j<9; j++) {
                scanf("%1d", &G[i][j]);
                int k = G[i][j];
                if(k != 0) {
                    row[i][k] = col[j][k] = sq[i/3][j/3][k] = true;
                }
                else q[cnt++] = (node){i, j};
            }
        }

        dfs(cnt-1);

        for(int i=0; i<9; i++) {
            for(int j=0; j<9; j++) {
                printf("%d", G[i][j]);
            }
            putchar('
');
        }
    }

    return 0;
}
原文地址:https://www.cnblogs.com/tanhehe/p/3243073.html