poj-2676

31 篇文章 0 订阅
// 356K 16MS    G++
#include <cstdio>
#include <queue>
#include <cstring>

#define MAX 9

using namespace std;

char initBoard[MAX][MAX];

int initFIlledNum;

void printBoard(char board[MAX][MAX]) {
    for (int i = 0; i < MAX; i++) {
        for (int j = 0; j < MAX; j++) {
            printf("%c", board[j][i] + '0');
        }
        printf("\n");
    }
}

char DFS(int beginX, int beginY, int filledNum) {
    if (filledNum == 81) {
        printBoard(initBoard);
        return 1;
    }

    int nextFillx = 0;
    int nextFilly = 0;

    for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
            if (initBoard[i][j] == 0) {
                nextFillx = i;
                nextFilly = j;
                break;
            }
        }
    }

    int rowNumMap[10] = {0};
    int columnNumMap[10] = {0};
    for (int i = 0; i < 9; i++) {
        int val1 = initBoard[i][nextFilly]; // check the row
        int val2 = initBoard[nextFillx][i]; // check the column
        if (val1 > 0) {
            rowNumMap[val1] = 1;
        }
        if (val2 > 0) {
            columnNumMap[val2] = 1;
        }
    }

    int matrixMap[10] = {0};
    int matrixBeginX = (nextFillx/3) * 3;
    int matrixBeginY = (nextFilly/3) * 3;

    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            int val = initBoard[matrixBeginX + i][matrixBeginY + j];
            if (val > 0) {
                matrixMap[val] = 1;
            }
        }
    }


    for (int i = 1; i < 10; i++) { // try fill some num
        if (!rowNumMap[i] && !columnNumMap[i] && !matrixMap[i]) {// if both the row and the column do not appear this num
            initBoard[nextFillx][nextFilly] = i;
            if (DFS(nextFillx, nextFilly, filledNum +1)) {
                return 1;
            }
            initBoard[nextFillx][nextFilly] = 0;
        }
    }
    return 0;
}

void solve() {
    // printBoard(initBoard);
    if (initFIlledNum == 81) {
        printBoard(initBoard);
        return;
    }
    DFS(0,0, initFIlledNum);
}

int main() {
    int caseNum;
    scanf("%d", &caseNum);
    for (int i = 0; i < caseNum; i++) {
        initFIlledNum = 0;
        for (int j = 0; j < MAX; j++) {
            char line[10];
            scanf("%s", line);
            for (int k = 0; k < MAX; k++) {
                initBoard[k][j] = line[k] - '0';
                if (initBoard[k][j] != 0) {
                    initFIlledNum++;
                }
            }
        }
        solve();
    }
}

经典的DFS题,顺带考察剪枝,一开始BFS习惯了,结果直接TLE,想想也是,这种只要求出一种答案就可以的题,DFS是第一选, BFS在这种情况下铺的大了点.

题最开始也没审清,光注意到每行每列不能有重复数字,没有注意到还要求3*3小矩阵也不能有重复的,WA了一次。

本身没啥可说的,这种DFS连checkFlag也不需要, 因为每次都一定是不同的局面(每次位置都不一样),每次DFS都从矩阵中找到第一个为0的空位,然后结合

行,列和3*3矩阵来决定可以在此位置填哪些值,继续DFS即可,每次DFS还要传递此轮DFS已经填好了多少个数字,当填够了9*9个以后,就可以打印矩阵并返回1了,

一开始在输入上面栽个跟头,因为数字是挨着的,所以%d不行,用%c,但是%c会把回车也算计来,后来就直接%s读每行然后挨个处理了,在输入时就统计初始的矩阵填好了多少个数字,如果给的是都填好的,直接返回就OK。

3074 是同样的题,但是给的第二组数据能卡死,看了下,都是用DLX才过的,以后要看看.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值