UESTC 数据结构

老头马桶枪!

Time Limit: 1000 MS     Memory Limit: 64 MB

众所周知,集训队的题目是非常困难的。因此,队员们在挂机AK之后,常常会玩一些游戏。

这次,率先AK的周大爷想出了一个叫老头马桶枪的游戏。

在一个小岛上,有三个物种,一共N个生物生活在一起,他们分别是老头、马桶和枪。他们之间的关系是相互克制的,就像包剪锤一样。老头克制马桶,马桶克制枪,枪又克制老头。

现在,集训队的三名成员,小周,小钱和小胡按次序(周、钱、胡)轮流给出信息,信息有两种形式:

第一种记录方式是1 X Y

,表示 X Y

是同类。

第二种记录方式是2 X Y

,表示 X Y有攻击性行为( X克制 Y

)。

当其中一人给出的信息和之前的人给出的信息矛盾时,他便输了,要请吃晚饭。那么,聪明的你能帮助他们看出谁会输呢?(最多只会有一个人输,当多条信息矛盾时,最先给出矛盾信息的人输)

Input

第一行包含两个整数N

M N是生物总个数, M是三个队员给出的信息总个数。以下 M行,每行包含一句队员的话。(依次是小周、小钱、小胡所说的话,三人轮流给出信息)。形式有 1 x y 2 x y 1N100000 1M100000 1X,YN

Output

输出一行,表示最先给出矛盾信息的人是谁。若是小周,输出1;若是小钱,输出2;若是小胡,输出3;若没有人给出矛盾信息,输出-1

Sample input and output

Sample Input Sample Output
100 7
1 100 1 
2 1 2
2 2 3 
2 3 3 
1 1 3 
2 3 1 
1 5 5
1

Source

2018 UESTC Training for Data Structures

UESTC Online Judge

Copyright (C) 2012 - 2018 Ruins He(@ruinshe), Jianjin Fan(@pfctgeorge) and Yun Li(@mzry1992). Project home

Any Problem, Please Report On Issues Page.

这一题仿照poj1182的食物链https://blog.csdn.net/keepcoral/article/details/79946060

食物链循环,a->b,b->c,c->a,这里学到一种新的方法,上面写的实在有点难懂,特别是推到关系那里,真的很难想,这里从别人博客上学到了新方法。

首先,有n个动物,那么我们开辟3n个集合,x,x+n,x+2n,分别表示与x同类,被x吃的,吃x的集合,所以两个动物x和y下面有两种情况:

1 x和y是同类,那么和y同类的即等价于和x同类,吃y的等价于吃x的,被y吃的等价于被x吃的,所以这三个集合要同时合并,

             Union(x,y);
             Union(x+n,y+n);
             Union(x+2*n,y+2*n)

判断真假条件:x被y吃||x吃y,那么直接表示就是x在y+n的集合||x在y+2n的集合,这里y+n代表被y吃的集合,y+2n代表吃y的集合,所以判断条件为judge(x,y+n)&&judge(x,y+2n),

2 x吃y,那么被y吃的等价于吃x的,和y同类的等价于被x吃的,吃y的等价于x的同类,所以集合为

                Union(x,y+n);
                Union(x+n,y+2*n);
                Union(x+2*n,y);

判断真假条件:x和y同类||y吃x,所以条件为 judge(x,y)&&judge(x,y+n)(我的代码可能会有点出入,因为n和2*n我写的恰好相反的)

这里的合并是最关键的操作,下面的几道题也是一样,也就是当不知道情况的时候才可以去合并,这是题目的要求

#include<iostream>
#include<string>
#include<vector>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<set>
#include<stack>
#include<queue>
#include<string>
#include<map>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
int father[300009];
int Find(int x)
{
    if(x!=father[x]) father[x]=Find(father[x]);
    return father[x];
}
int Union(int x,int y)
{
    int i=Find(x);
    int j=Find(y);
    if(i!=j) father[i]=j;
}
int judge(int x,int y)
{
    int i=Find(x);
    int j=Find(y);
    if(i!=j)//不同类
    {
        return 1;
    }
    else return 0;
}
int main()
{
    int n,m,i,j,k;
    scanf("%d%d",&n,&m);
    for(i=1;i<=3*n;i++) father[i]=i;
    for(i=1; i<=m; i++)
    {
        int op,x,y;
        scanf("%d%d%d",&op,&x,&y);
        if(op==1)//x和y是同类,所以判断不同类
        {
            if(judge(x,y+n)&&judge(x,y+2*n))
            {
                Union(x,y);
                Union(x+n,y+n);
                Union(x+2*n,y+2*n);
            }
            else
            {
                if(i%3!=0)printf("%d\n",i%3);
                else printf("3\n");
                break;
            }
        }
        else//x吃y,要判断同类或者y吃x
        {
            if(judge(x,y)&&judge(x,y+2*n))
            {
                Union(x,y+n);
                Union(x+n,y+2*n);
                Union(x+2*n,y);
            }
            else
            {
                if(i%3!=0)printf("%d\n",i%3);
                else printf("3\n");
                break;
            }
        }
    }
    if(i==m+1) printf("-1\n");
    return 0;
}

I - 不如把并查集加上个计数功能吧

Time Limit: 1000 MS     Memory Limit: 64 MB

在另一个宇宙,一个月有 N

天。多变的天气条件使得人们很恼火,终于,天气统计局产生了。它会对外发布 M 条信息,格式如下: X Y 表示第 X 天的天气和第 Y

天一样。

但民众并不满足于此,他们想知道有多少天的天气和第 X

天一样。现在,作为一个聪明的程序员,你能帮他们解决这个问题吗?

Input

第一行包含两个整数N

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值