您的位置:首页 > 其它

2546 奇偶游戏

2016-08-30 15:48 155 查看

2546奇偶游戏

时间限制:1s

空间限制:128000KB

题目等级:钻石Diamond

题解

题目描述Description

你和你的朋友玩一个游戏。你的朋友写下来一连串的0或者1。你选择一个连续的子序列然后问他,这个子序列包含1的个数是

奇数还是偶数。你的朋友回答完你的问题,接着你问下一个问题。

你怀疑你朋友的一些答案可能是错误的,你决定写一个程序来帮忙。程序将接受一系列你的问题及你朋友的回答,程序的目的

是找到第一个错误的回答i,也就是存在一个序列满足前i-1个问题的答案,但是不满足前i个问题。



输入描述InputDescription

第一行有一个整数L(L<=1000000000),是这个01序列的长度。第二行是一个整数N(N<=5000),是问题及其答案的数目,

接下来N行描述问题和答案。每一行包含一个问题和这个问题的答案:

两个整数(子序列的起始位置和结束位置)和一个单词‘even’或者‘odd’,

‘even’表示这个子序列中的‘1’的个数是偶数,

‘odd’则表示是奇数。


输出描述OutputDescription

只需输出一行一个整数X。

表示存在一个01序列满足前面的X个问题,但是不存在一个01序列满足前X+1个问题,如果存在一个序列满足所有问题,

则输出N。


样例输入SampleInput

10

5

12even

34odd

56even

16even

710odd


样例输出SampleOutput

3

数据范围及提示DataSize&Hint

分类标签Tags点此展开

并查集树结构
[b]题解:[/b]
类似“食物链”的做法2
分析关系即可。

ps:注意位运算
<<1|1==*2+1(正确)
>>1|1==/2+1(错误)
[b]AC代码:[/b]

#include<cstdio>
#include<algorithm>
usingnamespacestd;
#defineN10010
structnode{
ints,pos;
booloperator<(constnode&a)const{returns<a.s;}
}t
;
intn,m,l
,r
,fa[N<<1];
booljudge
;
intfind(intx){
returnfa[x]==x?x:fa[x]=find(fa[x]);
}
voidmerge(inta,intb){
intx=find(a),y=find(b);
if(x!=y)fa[x]=y;
}
intmain(){
scanf("%d%d",&n,&m);
for(inti=1,u,v;i<=m;i++){
charstr[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(inti=1;i<=m<<1;i++)t[i].pos=i;
sort(t+1,t+(m<<1|1));
intres=0;t[0].s=-1;
for(inti=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;
elser[t[i].pos>>1]=res;
}
for(inti=1;i<=res<<1;i++)fa[i]=i;
n=res;
for(inti=1;i<=m;i++){
intu=l[i],v=r[i];
if(!judge[i]){
if(find(u)==find(v+n)||find(u+n)==find(v)){printf("%d",i-1);return0;}
merge(u,v);
merge(u+n,v+n);
}
else{
if(find(u)==find(v)){printf("%d",i-1);return0;}
merge(u,v+n);
merge(v,u+n);
}
}
printf("%d",m);
return0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: