有 N 个虫洞,将这些虫洞两两分组,同组的两个虫洞可以互相到达,使得奶牛从坐标系某个位置出发,一直沿+x 方向走时会陷入无限循环
因为 N <= 12 比较小,可以枚举所有的两两连接情况,然后判断可行不可行
#include <cstdio>
using namespace std;
const int MAX_N=12;
int N, x[MAX_N + 1], y[MAX_N + 1];
int next[MAX_N + 1], p[MAX_N + 1];
bool check(void)
{
for (int i=1; i<=N; i++){
int pos = i; // every start
for (int j=1; j<=N; j++) pos = next[p[pos]];
if(pos != 0) return true;
}
return false;
}
int doit(void)
{
// counting all possible cases
int i, ret=0;
for (i=1; i<=N; i++)
if(p[i] == 0) { i=i; break; } // finding the wormhole haven't be paired
if (i>N){ // there is not unpaired wormhole
if(check()) return 1;
return 0;
}
for (int j=i+1; j<=N; j++) // pairing i with j
if(p[j] == 0){
p[j] = i; p[i] = j;
ret += doit();
p[j] = p[i] = 0;
}
return ret;
}
int main(void)
{
freopen("wormhole.in", "r", stdin);
freopen("wormhole.out", "w", stdout);
scanf("%d", &N);
for (int i=1; i<=N; i++) scanf("%d%d", &x[i], &y[i]); // cin
for (int i=1; i<=N; i++)// finding next[]
for (int j=1; j<=N; j++){
if (x[i] < x[j] && y[i] == y[j]){
if (next[i] == 0 || x[j] - x[i] < x[next[i]] - x[i]) // haven't got or closer
next[i] = j;
}
}
printf("%d\n", doit());
return 0;
}