您的位置:首页 > 其它

ZOj 1008 Gnome Tetravex

2012-07-19 22:15 330 查看
又是一题典型的深搜题。但是当你知道这是深搜之后,仅仅只是开始,因为25!的复杂度是相当惊人的。只有进行必要的剪枝之后才能AC,我在连续TLE几次之后,在大神的指导下终于 A过了。这里是剪掉了对相同卡片的 尝试操作。

#include <stdio.h>
#include <string.h>
#define MAXN (5+5)

typedef struct
{
    int top;
    int right;
    int bottom;
    int left;
}Node;

Node card[MAXN*MAXN],att[MAXN*MAXN];
int step[MAXN*MAXN],avail[MAXN*MAXN];
int N,isend;

int isequal( Node x,Node y)
{
    if( x.left==y.left &&x.top==y.top &&x.right==y.right &&x.bottom==y.bottom )
        return 1;
    return 0;
}

void swap( Node *x, Node *y )
{
    Node temp;
    temp=*x;
    *x=*y;
    *y=temp;
}

void init()
{
    int i,j,k;
    isend=0;

    for ( i=0,k=0; i<N*N; i+=step[k] ,k++ )
    {
        step[k]= avail[k]= 1;
        for( j=i+1; j<N*N; j++ )
            if( isequal(card[i],card[j]) )
            {
                swap( &card[j] ,&card[i+step[k]] );
                step[k]++;  avail[k]++;
            }
    }

}

int isvalid(int cur,int i)
{
    int line=cur/N;
    int row=cur-N*line;
    int flag=1;
    if( line>0 && card[i].top != att[(line-1)*N+row].bottom )
        flag=0;
    if( row>0 && card[i].left != att[cur-1].right )
        flag=0;
    return flag;
}

void dfs(int cur)
{
    int i,k;
    if( cur == N*N ) isend=1;
    else
    {
        for( i = 0 ,k=0; !isend && i < N*N ; i+=step[k] ,k++)
            if( avail[k] && isvalid(cur,i) )
            {
                att[cur] = card[i];
                avail[k]--;
                dfs( cur+1 );
                avail[k]++;
            }
    }
}

int main()
{
    int i,number=1;
    while ( scanf("%d",&N) && N!=0 )
    {
        for( i=0; i<N*N; i++)
            scanf("%d%d%d%d",&card[i].top,&card[i].right,&card[i].bottom,&card[i].left);
        init();
        dfs(0);
        if( number!=1 ) printf("\n");
        printf("Game %d: %s\n",number++,isend ? "Possible": "Impossible");
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: