首页 > 搜索 > DFS搜索 > HDU 4069-Squiggly Sudoku-DFS-[解题报告]HOJ
2015
04-16

HDU 4069-Squiggly Sudoku-DFS-[解题报告]HOJ

Squiggly Sudoku

问题描述 :

Today we play a squiggly sudoku, The objective is to fill a 9*9 grid with digits so that each column, each row, and each of the nine Connecting-sub-grids that compose the grid contains all of the digits from 1 to 9.
Left figure is the puzzle and right figure is one solution.
SanguoSHA

Now, give you the information of the puzzle, please tell me is there no solution or multiple solution or one solution.

输入:

The first line is a number T(1<=T<=2500), represents the number of case. The next T blocks follow each indicates a case.
Each case contains nine lines, Each line contains nine integers.
Each module number tells the information of the gird and is the sum of up to five integers:
0~9: ’0′ means this gird is empty, ’1′ – ’9′ means the gird is already filled in.
16: wall to the up
32: wall to the right
64: wall to the down
128: wall to the left
I promise there must be nine Connecting-sub-grids, and each contains nine girds.

输出:

The first line is a number T(1<=T<=2500), represents the number of case. The next T blocks follow each indicates a case.
Each case contains nine lines, Each line contains nine integers.
Each module number tells the information of the gird and is the sum of up to five integers:
0~9: ’0′ means this gird is empty, ’1′ – ’9′ means the gird is already filled in.
16: wall to the up
32: wall to the right
64: wall to the down
128: wall to the left
I promise there must be nine Connecting-sub-grids, and each contains nine girds.

样例输入:

3
144 18 112 208 80 25 54 144 48
135 38 147 80 121 128 97 130 32
137 32 160 144 114 167 208 0 32
192 100 160 160 208 96 183 192 101
209 80 39 192 86 48 136 80 114
152 48 226 144 112 160 160 149 48
128 0 112 166 215 96 160 128 41
128 39 153 32 209 80 101 136 35
192 96 200 67 80 112 208 68 96 

144 48 144 81 81 16 53 144 48
128 96 224 144 48 128 103 128 38
163 208 80 0 37 224 209 0 32
135 48 176 192 64 112 176 192 104
192 101 128 89 80 82 32 150 48
149 48 224 208 16 48 224 192 33
128 0 114 176 135 0 80 112 169
137 32 148 32 192 96 176 144 32
192 96 193 64 80 80 96 192 96

144 88 48 217 16 16 80 112 176
224 176 129 48 128 40 208 16 37
145 32 128 96 196 96 176 136 32
192 32 227 176 144 80 96 192 32
176 192 80 98 160 145 80 48 224
128 48 144 80 96 224 183 128 48
128 36 224 144 51 144 32 128 105
131 64 112 136 32 192 36 224 176
224 208 80 64 64 116 192 83 96

样例输出:

Case 1:
521439678
763895124
984527361
346182795
157964832
812743956
235678419
479216583
698351247
Case 2:
No solution
Case 3:
Multiple Solutions

跟普通的数独有一点点不同,先预处理一下再用Dancing Links进行精确覆盖即可。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxn = 9*9*9*9*9*4 + 10;
const int oo = 1 << 30;
const int maxrow = 9*9*9 + 10;
const int maxcol = 9*9*4 + 10;
int mtx[maxrow][maxcol];
int sub[10][10];
int map[10][10];
int ansMap[10][10];

int totRow, totCol, head, idx;
int L[maxn], R[maxn], U[maxn], D[maxn];
int RH[maxn], CH[maxn], S[maxn];
int t, ans;

void initMtx()
{
    memset(mtx, 0, sizeof(mtx));
    for (int i = 0; i < 9; ++i) {
        for (int j = 0; j < 9; ++j) {
            int t = i * 9 + j;
            if (map[i][j] == 0) {
                for (int k = 0; k < 9; ++k) {
                    int row = t * 9 + k;
                    mtx[row][t] = 1;
                    mtx[row][i*9+k+81] = 1;
                    mtx[row][j*9+k+162] = 1;
                    mtx[row][sub[i][j]*9+k+243] = 1;
                }
            } else {
                int k = map[i][j] - 1;
                int row = t * 9 + k;
                mtx[row][t] = 1;
                mtx[row][i*9+k+81] = 1;
                mtx[row][j*9+k+162] = 1;
                mtx[row][sub[i][j]*9+k+243] = 1;
            }
        }
    }
}

int newNode(int up, int down, int left, int right)
{
    U[idx] = up;    D[idx] = down;
    L[idx] = left;  R[idx] = right;
    U[down] = D[up] = L[right] = R[left] = idx;
    return idx++;
}

void build()
{
    idx = maxn - 1;
    head = newNode(idx, idx, idx, idx);
    idx = 0;
    for (int j = 0; j < totCol; ++j) {
        newNode(idx, idx, L[head], head);
        CH[j] = j;  S[j] = 0;
    }
    for (int i = 0; i < totRow; ++i) {
        int k = -1;
        for (int j = 0; j < totCol; ++j) {
            if (!mtx[i][j]) continue;
            if (-1 == k) {
                k = newNode(U[CH[j]], CH[j], idx, idx);
                RH[k] = i;  CH[k] = j;  S[j]++;
            } else {
                k = newNode(U[CH[j]], CH[j], k, R[k]);
                RH[k] = i;  CH[k] = j;  S[j]++;
            }
        }
    }
}

inline void remove(int c)
{
    L[R[c]] = L[c];
    R[L[c]] = R[c];
    for (int i = D[c]; i != c; i = D[i]) {
        for (int j = R[i]; j != i; j = R[j]) {
            U[D[j]] = U[j];  D[U[j]] = D[j];  S[CH[j]]--;
        }
    }
}

inline void resume(int c)
{
    L[R[c]] = c;
    R[L[c]] = c;
    for (int i = U[c]; i != c; i = U[i]) {
        for (int j = L[i]; j != i; j = L[j]) {
            U[D[j]] = j;  D[U[j]] = j;  S[CH[j]]++;
        }
    }
}

int dance()
{
    if (R[head] == head) {
        if (ans == 0) {
            for (int i = 0; i < 9; ++i) {
                for (int j = 0; j < 9; ++j) {
                    ansMap[i][j] = map[i][j];
                }
            } 
        }
        return ++ans;
    }
    int i, j, k, c, min = oo;
    for (j = R[head]; j != head; j = R[j]) {
        if (S[j] < min) {
            min = S[j];  c = j;
        }
    }
    remove(c);
    for (i = D[c]; i != c; i = D[i]) {
        k = RH[i];
        map[k/9/9][(k/9)%9] = (k % 9) + 1;
        for (j = R[i]; j != i; j = R[j]) {
            remove(CH[j]);
        }
        if (dance() >= 2) {
            return 2;
        }
        for (j = L[i]; j != i; j = L[j]) {
            resume(CH[j]);
        }
        map[k/9/9][(k/9)%9] = 0;
    }
    resume(c);
    return 0;
}

inline bool hasWall(int x, int y, int d)
{
    int tmp = map[x][y] / 16;
    return tmp & (1 << d);
}

void dfs(int x, int y, int id)
{
    if (sub[x][y] != -1) {
        return ;
    }
    sub[x][y] = id;
    if (!hasWall(x, y, 0)) {
        dfs(x - 1, y, id);
    }
    if (!hasWall(x, y, 1)) {
        dfs(x, y + 1, id); 
    }
    if (!hasWall(x, y, 2)) {
        dfs(x + 1, y, id);
    }
    if (!hasWall(x, y, 3)) {
        dfs(x, y - 1, id);
    }
}

int main()
{
    totRow = 9*9*9, totCol = 9*9*4;
    scanf("%d", &t);
    for (int cas = 1; cas <= t; ++cas) {
        for (int i = 0; i < 9; ++i) {
            for (int j = 0; j < 9; ++j) {
                scanf("%d", &map[i][j]);
            } 
        }
        memset(sub, -1, sizeof(sub));
        int id = 0;
        for (int i = 0; i < 9; ++i) {
            for (int j = 0; j < 9; ++j) {
                if (sub[i][j] == -1) {
                    dfs(i, j, id);
                    id++;
                }
            }
        }
        for (int i = 0; i < 9; ++i) {
            for (int j = 0; j < 9; ++j) {
                map[i][j] %= 16;
            }
        }
        initMtx();
        build();
        ans = 0;
        dance();
        
        printf("Case %d:\n", cas);
        if (ans == 0) {
            printf("No solution\n");
        } else if (ans > 1) {
            printf("Multiple Solutions\n");
        } else {
            for (int i = 0; i < 9; ++i) {
                for (int j = 0; j < 9; ++j) {
                    printf("%d", ansMap[i][j]);
                }
                printf("\n");
            } 
        }
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

参考:http://blog.csdn.net/ahfywff/article/details/7940402


,
  1. for(int i=1; i<=m; i++){
    for(int j=1; j<=n; j++){
    dp = dp [j-1] + 1;
    if(s1.charAt(i-1) == s3.charAt(i+j-1))
    dp = dp[i-1] + 1;
    if(s2.charAt(j-1) == s3.charAt(i+j-1))
    dp = Math.max(dp [j - 1] + 1, dp );
    }
    }
    这里的代码似乎有点问题? dp(i)(j) = dp(i)(j-1) + 1;这个例子System.out.println(ils.isInterleave("aa","dbbca", "aadbbcb"));返回的应该是false