zoukankan      html  css  js  c++  java
  • poj2676(数独)

    也是一个简单剪枝的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;
    }
  • 相关阅读:
    Ceph性能优化
    查看linux中的TCP连接数
    从 PC 卸载 Office
    VDI数据恢复
    xencenter迁移云主机方法
    深入解析UUID及其应用(转载)
    XenServer master主机的作用
    解决CentOS下可以ping通ip ping不通域名
    利用Powershell查询AD中账号属性
    创建进程的第二种方法,以后很多都用这个方法。
  • 原文地址:https://www.cnblogs.com/caiminfeng/p/4920596.html
Copyright © 2011-2022 走看看