USACO_Wormholes

1 篇文章 0 订阅
1 篇文章 0 订阅

原题地址
题目大意:
一个二维图上有N个虫洞(N一定是偶数),从一个虫洞可以直接传送到另一个和它相连的虫洞,(有且只有一个虫洞与某个虫洞相连)。进入虫洞的方向和出虫洞的方向一致。给出虫洞的坐标,问存在几种配对的方式使得小明(雾)从某个点出发回陷入无限循环..
一点感想..
这道题在搞组合的时候就出了点问题,一下子不知道怎么去除重复的组合..然后看了官方的解题视频,被震惊了..
直接用partner数组保存和某一虫洞相连的虫洞,找到一个没有配对的点就break所以可以保证不会产生重复的排列。保存离某个虫洞最近的那一个虫洞的下标(没有则为0),然后传送N次,如果还没传送出去就说明是无限循环。

代码

#include<iostream>
#include<algorithm>
#include<fstream>
using namespace std;
#define MAXN 12
int partner[MAXN+1],x[MAXN+1],y[MAXN+1],right_next[MAXN+1];
int N;
bool judge()
{
    int pos;
    for(int start = 1;start<=N;start++){
        pos = start;
        for(int i = 0;i<N;i++){
            pos = partner[right_next[pos]];
        }
        if(pos!=0)
            return true;
    }
    return false;
}
int solve()
{
    int i,ret = 0;
    for(i = 1;i<=N;i++)
        if(!partner[i])
            break;
    if(i == N + 1)
    {
        if(judge())
            ret++;
        return ret;
    }
    for(int j = i + 1;j<=N;j++){
        if(!partner[j]){
            partner[i] = j;
            partner[j] = i;
            ret += solve();
            partner[i] = partner[j] = 0;
        }
    }
    return ret;
}
int main()
{
    ifstream fin("wormhole.in");
    ofstream fout("wormhole.out");
    fin>>N;
    for(int i = 1;i<=N;i++)
        fin>>x[i]>>y[i];
    for(int i = 1;i<=N;i++)
    {
        for(int j = 1;j<=N;j++)
        {
            if(x[j] > x[i] && y[i] == y[j])
                if(right_next[i] == 0||x[j]-x[i]<x[right_next[i]]-x[i])
                    right_next[i] = j;
        }
    }

    fout<<solve()<<endl;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值