usaco.section1.3 wormhole(枚举)

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;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值