分析:很有意思的一道题目,本菜调了一下午没有调出来,估计是判环过程出了问题,最后还是参照了官方题解。暴力去求解,首先预处理当前位置出洞以后将会进入的下一个位置,然后用回溯法去枚举每一对组合,在进行判环,这题收获还是很大。
1 /* 2 PROB:wormhole 3 ID:wanghan 4 LANG:C++ 5 */ 6 #include "iostream" 7 #include "cstdio" 8 #include "cstring" 9 using namespace std; 10 const int maxn=20; 11 int n; 12 int x[maxn],y[maxn]; 13 int Next[maxn],par[maxn]; 14 bool Cycle(){ 15 for(int i=1;i<=n;i++){ 16 int pos=i; 17 for(int j=0;j<n;j++){ 18 pos=Next[par[pos]]; 19 } 20 if(pos!=0) return true; 21 } 22 return false; 23 } 24 int solve(){ 25 int i,res=0; 26 for(i=1;i<=n;i++) 27 if(par[i]==0) break; 28 if(i>n){ 29 if(Cycle()) return 1; 30 return 0; 31 } 32 for(int j=i+1;j<=n;j++){ 33 if(par[j]==0){ 34 par[i]=j; 35 par[j]=i; 36 res+=solve(); 37 par[i]=par[j]=0; 38 } 39 } 40 return res; 41 } 42 int main() 43 { 44 freopen("wormhole.in","r",stdin); 45 freopen("wormhole.out","w",stdout); 46 cin>>n; 47 for(int i=1;i<=n;i++) 48 cin>>x[i]>>y[i]; 49 for(int i=1;i<=n;i++){ //预处理当前位置出洞会达到的位置 50 for(int j=1;j<=n;j++){ 51 if(y[j]==y[i]&&x[j]>x[i]){ 52 if(Next[i]==0||x[j]-x[i]<x[Next[i]]-x[i]) 53 Next[i]=j; 54 } 55 } 56 } 57 cout<<solve()<<endl; 58 }