• 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;
    } 
     
  • 相关阅读:
    SQL中JOIN 的用法
    ava中普通代码块,构造代码块,静态代码块区别及示例
    javabean的内省技术和BeanUtils的使用
    Tomcat服务器学习和使用(一)
    增强For循环
    JAVA单态设计模式
    关于枚举的整理
    java中遍历MAP的几种方法
    equals和==的区别
    深入剖析Java中的装箱和拆箱
  • 原文地址:https://www.cnblogs.com/shenben/p/5822323.html
Copyright © 2020-2023  润新知