hdu 6341 Problem J. Let Sudoku Rotate(数独)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=6341

思路:
预处理每一个4*4 格子旋转的四种状态。
然后dfs即可,时间上限4^(16) 但是实际上
数独限制较多,大多数情况中途已经剪掉。

代码: 

#include<bits/stdc++.h>
using namespace std;
char txt[20][20];
int a[5][4][4][4][4],ans;
bool L[20][20],R[20][20];
void init()
{
    for(int i=0; i<16; i++)
    {
        for(int j=0; j<16; j++)
        {
            int c;
            if(txt[i][j]>='0'&&txt[i][j]<='9')
                c=txt[i][j]-'0';
            else
                c=txt[i][j]-'A'+10;
            a[0][i/4][j/4][i%4][j%4]=c;
            a[4][i/4][j/4][i%4][j%4]=c;
        }
    }
    for(int k=1; k<4; k++)
        for(int i=0; i<4; i++)
            for(int j=0; j<4; j++)
                for(int x=0; x<4; x++)
                    for(int y=0; y<4; y++)
                        a[k][i][j][x][y]=a[k-1][i][j][3-y][x];
}
bool check(int x,int y,int k)
{
    for(int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            int c=a[k][x][y][i][j];
            if(L[x*4+i][c]) return 0;
            if(R[y*4+j][c]) return 0;
        }
    }
    return 1;
}
void change(int x,int y,int k,bool C)
{
    for(int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            int c=a[k][x][y][i][j];
            L[x*4+i][c]=C;
            R[y*4+j][c]=C;
        }
    }
}
void dfs(int x,int y,int step)
{
    if(step>=ans) return;
    if(x==4)
    {
        ans=min(ans,step);
        return;
    }
    for(int i=0;i<4;i++)
    {
        if(check(x,y,i))
        {
            change(x,y,i,1);
            if(y<3) dfs(x,y+1,step+i);
            else dfs(x+1,0,step+i);
            change(x,y,i,0);
        }
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        for(int i=0; i<16; i++)
            scanf("%s",&txt[i]);
        init();
        memset(L,0,sizeof(L));
        memset(R,0,sizeof(R));
        ans=1e9;
        dfs(0,0,0);
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/albertluf/article/details/81432691
今日推荐