码迷,mamicode.com
首页 > 其他好文 > 详细

poj2676(数独)

时间:2015-10-29 16:15:33      阅读:125      评论:0      收藏:0      [点我收藏+]

标签:

也是一个简单剪枝的dfs。记录所有为0的位置,依次填写,当发现某个空格可选的填写数字已经没有时,说明该支路无效,剪掉。

不算是一个难题吧,但是还是花了不少时间,问题主要出在细节上,行列坐标反了、3乘3小格的位置判断等。写程序一定要细心。

#include <iostream>
using namespace std;

const int MAX_R = 9;
int map[MAX_R + 1][MAX_R + 1];
int zero_pos[MAX_R * MAX_R][2];
int possible_digits[MAX_R * MAX_R][9];
int zero_cnt;

int setPossibleDigits(int x, int y, int s)
{
    bool possible[10];
    memset(possible, 0, sizeof(possible));
    for (int i = 1; i <= MAX_R; i++){
        possible[map[i][x]] = true;
        possible[map[y][i]] = true;
    }
    int subX = (x - 1) / 3;
    int subY = (y - 1) / 3;
    for (int i = subX * 3 + 1; i <= subX * 3 + 3; i++){
        for (int j = subY * 3 + 1; j <= subY * 3 + 3; j++){
            possible[map[j][i]] = true;
        }
    }
    int cnt = 0;
    for (int i = 1; i <= 9; i++){
        if (!possible[i])
            possible_digits[s][cnt++] = i;
    }
    return cnt;
}

bool dfs(int step)
{
    if (step == zero_cnt){
        return true;
    }
    int curX = zero_pos[step][1],
        curY = zero_pos[step][0];
    int possible_cnt = setPossibleDigits(curX, curY, step);
    if (possible_cnt == 0){
        return false;
    }
    for (int i = 0; i < possible_cnt; i++){
        map[curY][curX] = possible_digits[step][i];
        if (dfs(step + 1))
            return true;
        else
            map[curY][curX] = 0;
    }
    return false;
}

int main()
{
    int t;
    cin >> t;
    while (t--){
        memset(map, 0, sizeof(map));
        memset(zero_pos, 0, sizeof(zero_pos));
        memset(possible_digits, 0, sizeof(possible_digits));
        zero_cnt = 0;
        for (int i = 1; i <= MAX_R; i++){
            for (int j = 1; j <= MAX_R; j++){
                char ch;
                cin >> ch;
                map[i][j] = ch - 0;
                if (map[i][j] == 0){
                    zero_pos[zero_cnt][0] = i;
                    zero_pos[zero_cnt++][1] = j;
                }
            }
        }
        dfs(0);
        for (int i = 1; i <= MAX_R; i++){
            for (int j = 1; j <= MAX_R; j++){
                cout << map[i][j];
            }
            cout << endl;
        }
    }
    return 0;
}

 

poj2676(数独)

标签:

原文地址:http://www.cnblogs.com/caiminfeng/p/4920596.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!