[POJ 1733 ---パリティゲーム]互いに素セット離散+の種類

[POJ 1733 ---パリティゲーム]互いに素セット離散+の種類

トピック出典:入力するようにクリックして、[POJ 1733 -パリティゲーム]

説明

さて、次に、あなたはあなたの友人と、次のゲームをプレイします。あなたの友人は、0と1からなる配列を下に書き込みます。あなたは(例えば包括的に5桁目に第三のサブシーケンス)の連続サブシーケンスを選択し、このサブシーケンスは、ものの偶数か奇数番号が含まれているかどうか、彼に尋ねます。あなたの友人は、あなたの質問に答えると、あなたは別のサブシーケンスについてと上のように、彼に尋ねることができます。あなたの仕事は数字のシーケンス全体を推測することです。

あなたの友人の答えの一部が正しくない可能性が疑われると、あなたは虚偽の彼を有罪にしたいです。したがって、あなたがこの問題であなたを助けるためにプログラムを書くことにしました。プログラムは、あなたがあなたの友人から受け取った答えと一緒にあなたの一連の質問を受けます。このプログラムの目的は、以前のすべての質問への回答を満たすシーケンスが存在すること、すなわち、証明可能間違っている最初の答えを見つけることですが、そのようなシーケンスを満たすこの回答。

入力

入力の最初の行は0と1のシーケンスの長さであるものの数を含んでいます。この長さが小さいか、2行目で1000000000に等しい、質問の数を求め、それらへの回答である一つの正の整数があります。質問と回答の数は以下5000の残りの行は、質問と回答を指定しています。二つの整数(選択したサブシーケンスの最初と最後の桁の位置)のいずれかである一のワード:各行は、1つの質問とこの質問への答えが含まeven' orすなわち内の1の数のパリティ奇数」(答えは、選択されたサブシーケンス、even' means an even number of ones and」奇数の奇数を意味します)。

出力

X.数Xは、最初のXパリティ条件を満たす0と1のシーケンスが存在することを述べている整数1を含む出力で唯一のラインがありますが、X + 1つの条件を満たすどれも存在しません。すべての与えられた条件を満たす0と1のシーケンスが存在する場合、その数のXは、すべての質問の数は尋ねなければなりません。

サンプル入力

10
5
1 2偶数
3 4奇数
5 6も
1 6も
7〜10の奇数

サンプル出力

3

問題解決のためのアイデア

xは、1の数との間のyが偶数である場合には、1〜1〜xとyの同じパリティの数、排他的逆のパリティに、我々は、入力されたX、Y、たとえとして理解することができますすなわち、X、Yは、そうでなければ、異なる種に属する、同じ種に属し、

三点に友達になれる互いに素セットのようなもの...しかし、注意を払うと、一つのデータは、直接ちょうどライン上にマッピングされたマップを使用して、このタイトルの下、当然の配列の添字、第1の離散を見て、使用することはできない、1E9の範囲、2番目が入力されデータは、x、yは閉区間、良好な加工であり、我々は、(X-1、Y]、半開区間に加工することができ、正しい、すべての出力Mが存在する場合。

ACコード:

#include <iostream>
#include <algorithm>
#include <map>
#include <cstring>
#include <string>
using namespace std;
#define SIS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define endl '\n'
const int MAXN = 1e4+5;
int pre[MAXN],rk[MAXN];

void init()
{
    memset(rk,0,sizeof(rk));
    for(int i=0;i<MAXN;i++)
        pre[i]=i;
}

int _find(int x)
{
    if(x==pre[x]) return x;
    int p=pre[x];
    pre[x]=_find(pre[x]);
    rk[x]^=rk[p];
    return pre[x];
}

bool unite(int a,int b,int c)
{
    int x=_find(a);
    int y=_find(b);
    if(x==y && rk[a]^rk[b]==c) return true;
    else if(x==y) return false;
    pre[x]=y;
    rk[x]=rk[a]^rk[b]^c;
    return true;
}

int main()
{
    SIS;
    int n,m,x,y,pos=0,ans=0;
    bool flag=false;
    string s;
    map<int,int> mp;
    cin >> n >> m;
    init();
    for(int i=1;i<=m;i++)
    {
        cin >> x >> y >> s;
        if(flag) continue;
        x--;
        int k=0;
        if(s[0]=='e') k=0;
        else k=1;
        if(!mp[x]) mp[x]=++pos;
        if(!mp[y]) mp[y]=++pos;
        if(!unite(mp[x],mp[y],k)) ans=i-1,flag=true;
        else if(i==m) ans=m;
    }
    cout << ans << endl;
    return 0;
}
公開された412元の記事 ウォンの賞賛135 ・は 40000 +を見て

おすすめ

転載: blog.csdn.net/qq_41879343/article/details/104164140