ZOJ 1008

这一题用了DFS对每一种方法进行尝试,直到有一种成功的就possible;

#include <iostream>
#include "string.h"
using namespace std;
int diff;
int card[26][4];          //用于记录不同卡片的上、右、下、左、方向的数字
int cardnum[26];          //记录每一种卡片的个数
int trueorder[26];         //记录已经排好序的卡片是哪一种卡片,
int n;               
bool dfs(int now){
    if(n*n==now)return true;
    for(int i=0;i<diff;i++){
        if(0==cardnum[i])continue;
        if(0!=now/n&&card[trueorder[now-n]][2]!=card[i][0])continue;      //有上一行就与上一行相邻数字进行对比  
        if(0!=now%n&&card[trueorder[now-1]][1]!=card[i][3])continue;      //有前一个就与前一个相邻数字进行对比
        trueorder[now]=i;                             //前面的条件都成立,就放入已经排好的顺序中
        cardnum[i]--;                                //此卡所在卡种数减一
        if(dfs(now+1))return true;                         //进行下一个排序
        else {
            cardnum[i]++;
        }
    }
    return false;
}
int main()
{
    int game=1,up,rig,dow,lef,j,i;
    while(cin>>n){
        if(n==0)break;
        memset(cardnum,0,sizeof(cardnum));
        memset(card,0,sizeof(card));
        diff=0;
        for( i=0;i<n*n;i++){
            cin>>up>>rig>>dow>>lef;
            for(j=0;j<diff;j++){
               if(card[j][0]==up&&card[j][1]==rig&&card[j][2]==dow&&card[j][3]==lef)break;      //判断是否已经有此卡种   
            }
            if(j==diff){                                //无此卡种则添加此卡种  
                cardnum[j]++;
                diff++;
                card[j][0]=up;
                card[j][1]=rig;
                card[j][2]=dow;
                card[j][3]=lef;
            }
            else cardnum[j]++;
        }  
        if(1!=game)cout<<endl;                        //注意换行   此处被坑了一次
        cout<<"Game "<<game<<": ";                        
        game++;
        if(dfs(0))
        cout<<"Possible ";
        else cout<<"Impossible ";
    }
    return 0;
}

原文地址:https://www.cnblogs.com/Mr-Xu-JH/p/3848179.html