USACO_Wormholes

原題地址
題目大意:
一個二維圖上有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;

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章