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\n";
        else cout<<"Impossible\n";
    }
    return 0;
}

转载于:https://www.cnblogs.com/Mr-Xu-JH/p/3848179.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值