搜索题,25个格子就要递归25!次,不过在递归时及时判断可以减少很多的递归次数,最开始写了个程序,竟然超时了,于是想各种各样的见剪枝方法,发现都很难实现。最后用了个开始自认为效果不太好的方法---将25个格子分类,相同的方在一起,这样在放try一个格子时就知用搜索那几个类别的格子了,没想到过了,用了8.83s,不过看到有些强人只用了0.00.33s,太不可思议了,不知道用的是怎样的剪枝大法。

//zju 1008
//by woodfish

#include <iostream>
using namespace std;


typedef struct Square
{
int top;
int bottom;
int left;
int right;
int num;
};

const int MAXN=5;
int n=0;
Square TTriangle;
Square Triangle[MAXN*MAXN];
Square DifTriangle[MAXN*MAXN];
int DifNum=0;
int game=0;


inline void GetXY(int pos,int& x,int& y)
{
x=pos/n;
y=pos%n;
}


bool Putcan(int pos,int i)
{
int x,y;
GetXY(pos,x,y);
if(x-1>=0)
if(Triangle[pos-n].bottom!=DifTriangle[i].top) return false;
if(y-1>=0)
if(Triangle[pos-1].right!=DifTriangle[i].left) return false;
return true;
}


inline void Move(int t,int i)
{
Triangle[t].bottom=DifTriangle[i].bottom;
Triangle[t].top=DifTriangle[i].top;
Triangle[t].left=DifTriangle[i].left;
Triangle[t].right=DifTriangle[i].right;
}


bool Try(int pos)
{
if(pos==n*n) return true;

else
{
for(int i=0;i<DifNum;i++)

if(DifTriangle[i].num>0&&Putcan(pos,i))
{
Move(pos,i);
DifTriangle[i].num--;
if(Try(pos+1)==true) return true;
DifTriangle[i].num++;
}
return false;
}
}


inline void Read(int n)
{
int j;
DifNum=0;

for(int i=0;i<n*n;i++)
{
cin>>TTriangle.top>>TTriangle.right>>TTriangle.bottom>>TTriangle.left;
for(j=0;j<DifNum;j++)
if( (TTriangle.bottom==DifTriangle[j].bottom)
&&(TTriangle.left==DifTriangle[j].left)
&&(TTriangle.right==DifTriangle[j].right)
&&(TTriangle.top==DifTriangle[j].top) )
break;

if(j==DifNum)
{
DifTriangle[j].bottom=TTriangle.bottom;
DifTriangle[j].top=TTriangle.top;
DifTriangle[j].left=TTriangle.left;
DifTriangle[j].right=TTriangle.right;
DifTriangle[j].num=1;
DifNum++;
}else
DifTriangle[j].num++;
}
}


int main()
{

while(cin>>n)
{
game++;
if(n==0) break;
Read(n);
if(game>1) cout<<endl;
cout<<"Game "<<game<<": ";
if(Try(0))
cout<<"Possible"<<endl;
else
cout<<"Impossible"<<endl;
}
return 1;
}

