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;
}