【♂Not The Triumph♂O(∩_∩)O哈哈~But The Struggle♂】

竞赛决不是捷径,它只是另一种艰辛的生活方式。得到与失去,只有时间会去评判;成功与失败,只有历史能去仲裁。我不会永远成功,正如我不会永远失败一样

  C++博客 :: 首页 :: 联系 ::  :: 管理
  6 Posts :: 239 Stories :: 25 Comments :: 0 Trackbacks

常用链接

留言簿(7)

我参与的团队

搜索

  •  

积分与排名

  • 积分 - 108422
  • 排名 - 229

最新评论

阅读排行榜

评论排行榜

你和一个朋友在玩一个游戏:他写一个由0和1组成的序列。
你选其中的一段(比如第3位到第5位),问他这段里面有奇数个1
还是偶数个1。你的朋友回答你的问题,然后你继续问。

你的朋友有可能在撒谎。你要检查他的答案,指出在他的第几个回答一定有问题。
有问题的意思就是存在一个01序列满足这个回答前的所有回答,而且不存在序列
满足这个回答前的所有回答及这个回答。
inout:

输入有多组数据。
每组数据的第1行一个整数,是这个01序列的长度(<=1000000000)
第2行一个整数,是问题和答案的个数。
第3行开始是问题和答案,
每行先有两个整数,表示你询问的段的开始位置和结束位置。
然后是你朋友的回答。odd表示有奇数个1,even表示有偶数个1。
输入文件以-1结束。

output:

每组测试数据输出一行,一个数X,表示存在一个01序列满足第1到第X个回答,
但是不存在序列满足第1到第X+1个回答。如果所有回答都没问题,你就输出
所有回答的个数。

input:

10
5
1 2 even
3 4 odd
5 6 even
1 6 even
7 10 odd
10
5
1 2 even
1 4 even
2 4 odd
1 10 even
3 10 even
-1

output:

3
5

分析:此题的大概思路是HASH+并查集,但是巧妙的是加上一个对立面(block),就是把两个结果映射在不同地方。

【参考程序】:

#include<iostream>
#include
<string>
using namespace std;
const int hashmax=6000;
const int block=10000;
int hash[20000],father[20000];
int len,n,ans;
int hash_make(int num)
{
    
int pos=num%hashmax;
    
while (hash[pos]!=-1 && hash[pos]!=num)
        pos
=(pos+1)%hashmax;
    hash[pos]
=num;
    
return pos;
}
int Find(int x)
{
    
/*int root=x;
    while (father[root]!=root) root=father[root];
    while (root!=x)
    {
        int temp=father[x];
        father[x]=root;
        x=temp;
    }
    return root;
*/
  
if (father[x]!=x) return Find(father[x]);
    
else return x;    
}
void Union(int x,int y)
{
    
int p=Find(x),q=Find(y);
    
if (p!=q) father[p]=q;
}
int main()
{
    
string st;int i;
    
while (cin>>len,len!=-1)
    {
        cin
>>n;
        
for (i=0;i<20000;i++) father[i]=i;
        memset(hash,
0xFF,sizeof(hash));
        
int a,b;
        
for (i=1;i<=n;i++)
        {
            cin
>>a>>b>>st;
            
bool EVEN=(st=="even");
            a
=hash_make(a-1);
            b
=hash_make(b);
            
if (EVEN)
            {//如果为偶,因为第一次我们全部是不同集合,那么a肯定和b的对立面是一个集合
                
if (Find(a)==Find(b+block)) break;
                Union(a,b);
                Union(a
+block,b+block);    
            }
            
else 
            {
                
if (Find(a)==Find(b)) break;
                Union(a
+block,b);
                Union(a,b
+block);
            }
        }
        ans
=i-1;
        
for (++i;i<=n;i++)
          cin
>>a>>b>>st;
        cout
<<ans<<endl;
    }
    
return 0;
}
posted on 2009-05-28 09:07 开拓者 阅读(234) 评论(0)  编辑 收藏 引用 所属分类: URAL 题解

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理