【POJ 2676】Sudoku

【POJ 2676】Sudoku

又是一个水数据的搜索……不过还是剪枝做了做 剪枝大法好啊!好多几百ms的 剪出来个0ms 顿感欣慰

不过看discuss 3074 Sudoku数据更强大 傻傻的去做了 最后T的实在不行的时候看到discuss说用dance links。。。呵呵了= = 只在当初听说xiao爷学了一阵子。。我还是慢慢搞吧= =有兴趣的可以去看看

回归此题。。我是存了三个数组分别标记行中哪些数能用 列中哪些数能用 子数独中哪些数能用 然后大胆的搜吧。。

剪枝我在每个白块后面加了个邻接表 刚才去掉一交跑了400多。。。也挺管用。。。吓死宝宝了……

代码如下:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>

using namespace std;

typedef struct Point
{
    int data,next;
}Point;

bool vsx[10][10],vsy[10][10],vshl[10][10];//行、列、子数独标记
char mp[10][11];
Point num[733];
int head[10][10];//空白块后的邻接表
int tp;

int gethl(int x,int y)//横总坐标转换子数独块下标。。推出来的
{
    return ((x+2)/3-1)*3 + (y+2)/3;
}

bool dfs(int x,int y)
{
    if(x == 9 && y == 9) return true;

    int i,data;
    x = (y == 9)? (x+1): x;
    y = (y == 9)? 1: (y+1);//y遍历到9时换行

    if(mp[x][y] != '0') return dfs(x,y);

    for(i = head[x][y]; i != -1; i = num[i].next)
    {
        data = num[i].data;
        if(vsx[x][data] || vsy[y][data] || vshl[gethl(x,y)][data]) continue;
        vsx[x][data] = vsy[y][data] = vshl[gethl(x,y)][data] = 1;
        mp[x][y] = '0'+data;
        if(dfs(x,y)) return true;
        vsx[x][data] = vsy[y][data] = vshl[gethl(x,y)][data] = 0;
    }
    mp[x][y] = '0';
    return false;
}

int main()
{
    int t,i,j,k;
    scanf("%d",&t);

    while(t--)
    {
        memset(vsx,0,sizeof(vsx));
        memset(vsy,0,sizeof(vsy));
        memset(vshl,0,sizeof(vshl));
        memset(head,-1,sizeof(head));
        tp = 0;
        for(i = 1; i <= 9; ++i)
        {
            scanf("%s",mp[i]+1);
            for(j = 1; j <= 9; ++j)
                if(mp[i][j] != '0')
                {
                    vsx[i][mp[i][j]-'0'] = 1;
                    vsy[j][mp[i][j]-'0'] = 1;
                    vshl[gethl(i,j)][mp[i][j]-'0'] = 1;
                }
        }

        for(i = 1; i <= 9; ++i)
            for(j = 1; j <= 9; ++j)
            {
                if(mp[i][j] != '0') continue;
                for(k = 1; k <= 9; ++k)
                    if(!vsx[i][k] && !vsy[j][k] && !vshl[gethl(i,j)][k])
                    {
                        num[tp].data = k;
                        num[tp].next = head[i][j];
                        head[i][j] = tp++;
                    }
            }

        dfs(1,0);
        for(i = 1; i <= 9; ++i) printf("%s\n",mp[i]+1);
    }
    return 0;
}

你可能感兴趣的:(dfs之剪枝)