ZOJ 1008 Gnome Tetravex(DFS)

题目链接

题意 : 将n*n个正方形进行排列,需要判断相邻的正方形的相邻三角形上边的数字是不是都相等。

思路 : 只知道是个深搜,一开始不知道怎么搜,后来看了题解才明白,就是说不是自己去搜,而是将给定的正方形按照要求一个个往上摆,如果摆不下去了肯定是没有结果的。还有可以将一样的放一起,如果一个在某个位置放不下了,那么其他的更放不下了。

#include <stdio.h>

#include <iostream>

#include <string.h>



using namespace std;



struct node

{

    int up,right,down,left;

    bool operator == (const node &a)

    {

        return up == a.up && right == a.right && down == a.down && left == a.left;

    }

} p[30];



int mapp[30][30];

int sum[30];

bool flag;

int n ;



void dfs(int s)

{

    if(s == n*n)

    {

        flag = true ;

        return ;

    }

    int x = s/n,y = s%n;

    for(int i = 0 ; i < n*n && !flag ; i++)

    {

        if(sum[i])//如果该正方形已经没有了,就用下一个

        {

                if(x > 0 && p[i].up != p[mapp[x-1][y]].down) continue;//如果这个正方形和前一个正方形在同一列,那这个的up应该与前一个down相同

                if(y > 0 && p[i].left != p[mapp[x][y-1]].right)  continue;

            mapp[x][y] = i ;//表明这个位置可以放

            --sum[i] ;

            dfs(s+1) ;

            ++sum[i] ;//还原

        }

    }

}



int main()

{

    int cas = 1 ;

    while(scanf("%d",&n) && n)

    {

        memset(sum,0,sizeof(sum));

        for(int i = 0 ; i < n*n ; ++i)

        {

            scanf("%d %d %d %d",&p[i].up,&p[i].left,&p[i].down,&p[i].right);

            flag = false ;

            for(int j = 0 ; j < i ; ++j)

                if(sum[j] && p[j] == p[i])//优化,防止重复

                {

                    ++sum[j];

                    flag = true;

                    break;

                }

            if(!flag)

                ++sum[i];

        }

        memset(mapp,0,sizeof(mapp));

        flag = false;

        dfs(0);

        if(cas > 1)

            printf("\n");

        printf("Game %d: ",cas++);

        if(flag)

            printf("Possible\n");

        else

            printf("Impossible\n");

    }

    return 0;

}
View Code

 

你可能感兴趣的:(gnome)