搜索题,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;
}