2546 奇偶游戏

2546 奇偶游戏

 

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 钻石 Diamond
 
 
 
题目描述  Description
     你和你的朋友玩一个游戏。你的朋友写下来一连串的0或者1。你选择一个连续的子序列然后问他,这个子序列包含1的个数是
奇数还是偶数。你的朋友回答完你的问题,接着你问下一个问题。
     你怀疑你朋友的一些答案可能是错误的,你决定写一个程序来帮忙。程序将接受一系列你的问题及你朋友的回答,程序的目的
是找到第一个错误的回答i,也就是存在一个序列满足前i-1个问题的答案,但是不满足前i个问题。
 
输入描述  Input Description
第一行有一个整数L(L<=1000000000),是这个01序列的长度。第二行是一个整数N(N<=5000),是问题及其答案的数目,
接下来N行描述问题和答案。每一行包含一个问题和这个问题的答案:
两个整数(子序列的起始位置和结束位置)和一个单词‘even’或者‘odd’,
‘even’表示这个子序列中的‘1’的个数是偶数,
‘odd’则表示是奇数。
输出描述  Output Description
只需输出一行一个整数X。
表示存在一个01序列满足前面的X个问题,但是不存在一个01序列满足前X+1个问题,如果存在一个序列满足所有问题,
则输出N。
样例输入  Sample Input
              10
               5
               1 2 even
               3 4 odd
               5 6 even
               1 6 even
               7 10 odd
样例输出  Sample Output

3

数据范围及提示  Data Size & Hint

  

分类标签 Tags 点此展开 
 
题解:
类似“食物链”的做法2
分析关系即可。
 
ps:注意位运算
<<1|1==*2+1(正确)
>>1|1==/2+1(错误)
AC代码:
#include<cstdio>
#include<algorithm>
using namespace std;
#define N 10010 
struct node{
    int s,pos;
    bool operator < (const node &a)const{return s<a.s;}
}t[N];
int n,m,l[N],r[N],fa[N<<1];
bool judge[N];
int find(int x){
    return fa[x]==x?x:fa[x]=find(fa[x]);
}
void merge(int a,int b){
    int x=find(a),y=find(b);
    if(x!=y) fa[x]=y;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1,u,v;i<=m;i++){
        char str[10];
        scanf("%d%d%s",&u,&v,str);
        t[(i<<1)-1].s=u-1;t[i<<1].s=v;
        if(str[0]=='o') judge[i]=1;
    }
    for(int i=1;i<=m<<1;i++) t[i].pos=i;
    sort(t+1,t+(m<<1|1));
    int res=0;t[0].s=-1;
    for(int i=1;i<=m<<1;i++){
        if(t[i].s!=t[i-1].s) res++;
        if(t[i].pos&1) l[(t[i].pos>>1)+1]=res;
        else r[t[i].pos>>1]=res;
    }
    for(int i=1;i<=res<<1;i++) fa[i]=i;
    n=res;
    for(int i=1;i<=m;i++){
        int u=l[i],v=r[i];
        if(!judge[i]){
            if(find(u)==find(v+n)||find(u+n)==find(v)){printf("%d",i-1);return 0;}
            merge(u,v);
            merge(u+n,v+n);
        }
        else{
            if(find(u)==find(v)){printf("%d",i-1);return 0;}
            merge(u,v+n);
            merge(v,u+n);
        }
    }
    printf("%d",m);
    return 0;
} 

 

 

转载于:https://www.cnblogs.com/shenben/p/5822323.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值