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("
");
        printf("Game %d: ",cas++);
        if(flag)
            printf("Possible
");
        else
            printf("Impossible
");
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/luyingfeng/p/3671973.html