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

typedef 
浙公网安备 33010602011771号