POJ2676 Sudoku

http://poj.org/problem?id=2676

题目解析:
一道数独题,一开始我想用三维数组a[i][j][k],用来表示i行j列可以选的数字,如果可以就赋值为true,否则为false,可惜这样超时了,因为每填一个数字都要更新三维数组。
这道题因为测试组的原因,正向搜索比逆向搜索要慢很多,也是提醒我们,要有逆向思维
用三个数组used1,used2,used3来表示行列和小九宫格里的状态就好了

还是太年轻了,只是一个八皇后问题的变形就不会了,智商太低了啊TAT

#include<iostream>
using namespace std;
#include<cstdio>
#include<cstring>


bool ans=false;

int couns=0;
bool used1[10][10];
bool used2[10][10];
bool used3[10][10];

void print(int a[][10])
{
    for(int i=1; i<=9; i++)
    {
        for(int j=1; j<=9; j++)
        {
            printf("%d",a[i][j]);
        }
        printf("\n");
    }
}

int get(int i,int j)
{
    int u;
    if(i>=1&&i<=3&&j>=1&&j<=3)
        u=1;
    else if(i>=4&&i<=6&&j>=1&&j<=3)
        u=4;
    else if(i>=7&&i<=9&&j>=1&&j<=3)
        u=7;
    else if(i>=1&&i<=3&&j>=4&&j<=6)
        u=2;
    else if(i>=1&&i<=3&&j>=7&&j<=9)
        u=3;
    else if(i>=4&&i<=6&&j>=4&&j<=6)
        u=5;
    else if(i>=4&&i<=6&&j>=7&&j<=9)
        u=6;
    else if(i>=7&&i<=9&&j>=7&&j<=9)
        u=9;
    else if(i>=7&&i<=9&&j>=4&&j<=6)
        u=8;
    return u;
}


void dfs(int c,int a[][10])
{
    if(ans)
        return ;
    if(c==couns)
    {
        print(a);
        ans=true;
        return ;
    }
    else
    {
        for(int i=9; i>=1; i--)
            for(int j=9; j>=1; j--)
                if(!a[i][j])
                {
                    for(int k=1; k<=9; k++)
                    {
                        int num=get(i,j);
                        if(used1[i][k]||used2[j][k]||used3[num][k])
                            continue;
                        a[i][j]=k;
                        used1[i][k]=true;
                        used2[j][k]=true;
                        used3[num][k]=true;
                        if(ans)
                            return ;
                        dfs(c+1,a);
                        if(ans)
                            return ;
                        used1[i][k]=false;
                        used2[j][k]=false;
                        used3[num][k]=false;
                        a[i][j]=0;
                    }
                    return;
                }


    }


}

int main()
{
    int T;
    int a[10][10];
    freopen("input_poj2276.txt","r",stdin);
    scanf("%d",&T);
    while(T--)
    {

        couns=0;
        memset(used1,false,sizeof(used1));
        memset(used2,false,sizeof(used2));
        memset(used3,false,sizeof(used3));
        for(int i=1; i<=9; i++)
        {
            for(int j=1; j<10; j++)
            {
                scanf("%1d",&a[i][j]);
                if(a[i][j])
                {
                    used1[i][a[i][j]]=true;
                    used2[j][a[i][j]]=true;
                    used3[get(i,j)][a[i][j]]=true;
                }
                else
                    couns++;
            }
        }
        ans=false;
        dfs(0,a);
    }
    return 0;
}

你可能感兴趣的:(搜索,数组,poj)