HDU-6341 Problem J. Let Sudoku Rotate(dfs 剪枝)

题目:有一个4*4*4*4的数独,每一横每一竖每一个小方块中都无重复的字母,即都为0-9,A-F.。有一个已经填好的数独,若干个4*4的方块被逆时针拧转了若干次,问拧转回来至少需要多少次。

思路:dfs,看起来复杂度会很大,但是数独的限制性较大,加个最优化剪枝和可行性剪枝(判断转到每一4*4的区域后是不是与前面的转好了的冲突)能减掉很多的可能性。

#include <bits/stdc++.h>
using namespace std;
int t,a[22][22];
int tmp[22][22]={0};
void rotat(int x,int y)
{
    for(int i=1;i<=4;i++)
        for(int j=1;j<=4;j++)
            tmp[j][4-i+1]=a[(x-1)*4+i][(y-1)*4+j];
    for(int i=1;i<=4;i++)
        for(int j=1;j<=4;j++)
            a[(x-1)*4+i][(y-1)*4+j]=tmp[i][j];
}
int book[22];
bool check(int x,int y)
{
    for(int i=x*4-3;i<=x*4;i++)
    {
        memset(book,0,sizeof book);
        for(int j=1;j<=y*4;j++)
        {
            if(!book[a[i][j]])
                book[a[i][j]]=1;
            else
                return 0;
        }
    }
    for(int j=y*4-3;j<=y*4;j++)
    {
        memset(book,0,sizeof book);
        for(int i=1;i<=x*4;i++)
        {
            if(!book[a[i][j]])
                book[a[i][j]]=1;
            else
                return 0;
        }
    }
    return 1;
}
int ans;
void dfs(int x,int y,int sum)
{
    if(sum>=ans) return;
    if(x==5)
    {
        ans=sum;
        return ;
    }
    int xx=x,yy=y+1;
    if(yy==5) {yy=1;xx++;}
    for(int i=0;i<4;i++)
    {
        if(i) rotat(x,y);
        if(check(x,y))
            dfs(xx,yy,sum+i);
    }
    rotat(x,y);
}
char s[22];
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        for(int i=1;i<=16;i++)
        {
            scanf("%s",s+1);
            for(int j=1;j<=16;j++)
            {
                if(s[j]>'9')
                    a[i][j]=s[j]-'A'+10;
                else a[i][j]=s[j]-'0';
            }
        }
        ans=55;
/*
        for(int i=1;i<=4;i++)
        {
            for(int j=1;j<=4;j++)
                printf("%2d ",a[4+i][2*4+j]);
            puts("");
        }
        puts("****************");
        rotat(2,3);
        for(int i=1;i<=4;i++)
        {
            for(int j=1;j<=4;j++)
                printf("%2d ",a[4+i][2*4+j]);
            puts("");
        }
*/
        dfs(1,1,0);
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/dllpXFire/article/details/81381183
今日推荐