http://acm.hdu.edu.cn/showproblem.php?pid=6341
搜索题。。
可行性剪枝结合最优解剪枝 说着简单 比赛都没敢往搜索想 直接跳了。。
using namespace std;
int mp[300];
int ans;
char ch[20][20];
void init()
{
    int i,j;
    for(i=0;i<10;i++) mp['0'+i]=i;
    for(i=0;i<6;i++) mp['A'+i]=10+i;
}
//sythahaha
void rotate(int x,int y)
{
    char tmp[20][20];
    int i,j,ii,jj;
    for(i=4*x,jj=4*y+4-1;i<4*x+4;i++,jj--)
    {
        for(j=4*y,ii=4*x;j<4*y+4;j++,ii++)
        {
            tmp[ii][jj]=ch[i][j];
        }
    }
    for(i=4*x;i<4*x+4;i++)
    {
        for(j=4*y;j<4*y+4;j++)
        {
            ch[i][j]=tmp[i][j];
        }
    }
}
bool judge(int x,int y)
{
    bool book[20];
    int i,j;
    for(i=4*x;i<4*x+4;i++)
    {
        memset(book,false,sizeof(book));
        for(j=0;j<4*y+4;j++)
        {
            if(book[mp[ch[i][j]]]) return false;
            book[mp[ch[i][j]]]=true;
        }
    }
    for(j=4*y;j<4*y+4;j++)
    {
        memset(book,false,sizeof(book));
        for(i=0;i<4*x+4;i++)
        {
            if(book[mp[ch[i][j]]]) return false;
            book[mp[ch[i][j]]]=true;
        }
    }
    return true;
}
void dfs(int x,int y,int cnt)
{
    int i;
    if(cnt>=ans) return;
    if(x==4&&y==0)
    {
        ans=min(ans,cnt);
        return;
    }
    for(i=0;i<4;i++)
    {
        if(judge(x,y))
        {
            if(y<3) dfs(x,y+1,cnt+i);
            else dfs(x+1,0,cnt+i);
        }
        rotate(x,y);
    }
}
int main()
{
    int t,i,j;
    init();
    scanf("%d",&t);
    while(t--)
    {
        for(i=0;i<16;i++)
        {
            scanf("%s",ch[i]);
        }
        ans=100;
        dfs(0,0,0);
        printf("%d\n",ans);
    }
    return 0;
}                










