hdu 6341 Let Sudoku Rotate(爆搜+剪枝)

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

思路:直接dfs,搜索每个格子是否符合,不符合就旋转,找到最小的

代码:

#include<bits/stdc++.h>
using namespace std;
char c[25][25];
int a[25][25];
int vis[25];
int ans,flag;
void rot(int x,int y)
{
    int b[4][4];
    for(int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            b[j][3-i]=a[i+x][j+y];
        }
    }
    for(int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            a[i+x][j+y]=b[i][j];
        }
    }
}
bool check(int x,int y)
{
    for(int i=x;i<x+4;i++)
    {
        flag++;
        for(int j=0;j<y+4;j++)
        {
            if(vis[a[i][j]]==flag)
                return 0;
            vis[a[i][j]]=flag;
        }
    }
    for(int j=y;j<y+4;j++)
    {
        flag++;
        for(int i=0;i<x+4;i++)
        {
             if(vis[a[i][j]]==flag)
                return 0;
            vis[a[i][j]]=flag;
        }
    }
    return 1;
}
void dfs(int x,int y,int sum)
{
    if(sum>=ans)
        return;
    if(x==4)
    {
        ans=min(ans,sum);
        return;
    }
    if(y==4)
         dfs(x+1,0,sum);
    for(int i=0;i<4;i++)
    {
        if(check(4*x,4*y))
            dfs(x,y+1,sum+i);
        rot(4*x,4*y);
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        for(int i=0;i<16;i++)
        {
            scanf("%s",c[i]);
        }
        memset(vis,0,sizeof(vis));
        flag=0;
        for(int i=0;i<16;i++)
        {
            for(int j=0;j<16;j++)
            {
                if(c[i][j]>='0'&&c[i][j]<='9')
                    a[i][j]=c[i][j]-'0';
                else a[i][j]=c[i][j]-'A'+10;
            }
        }
        ans=55555;
        dfs(0,0,0);
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/imzxww/article/details/81415116