ZOj 1008 Gnome Tetravex

又是一題典型的深搜題。但是當你知道這是深搜之後,僅僅只是開始,因爲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;
}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章