zoukankan      html  css  js  c++  java
  • Day5

    动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形。A吃B, B吃C,C吃A。
    现有N个动物,以1-N编号。每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种。
    有人用两种说法对这N个动物所构成的食物链关系进行描述:
    第一种说法是"1 X Y",表示X和Y是同类。
    第二种说法是"2 X Y",表示X吃Y。
    此人对N个动物,用上述两种说法,一句接一句地说出K句话,这K句话有的是真的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。
    1) 当前的话与前面的某些真的话冲突,就是假话;
    2) 当前的话中X或Y比N大,就是假话;
    3) 当前的话表示X吃X,就是假话。
    你的任务是根据给定的N(1 <= N <= 50,000)和K句话(0 <= K <= 100,000),输出假话的总数。

    Input

    第一行是两个整数N和K,以一个空格分隔。
    以下K行每行是三个正整数 D,X,Y,两数之间用一个空格隔开,其中D表示说法的种类。
    若D=1,则表示X和Y是同类。
    若D=2,则表示X吃Y。

    Output

    只有一个整数,表示假话的数目。

    Sample Input

    100 7
    1 101 1 
    2 1 2
    2 2 3 
    2 3 3 
    1 1 3 
    2 3 1 
    1 5 5
    

    Sample Output

    3
    思路:只有三种动物,那就可以假设为i+0*N,i+1*N,i+2*N分别为ABC动物,同类时判断i与j是否是同一类,因为不知道究竟是ABC哪一个,就将ABC三种情况都合并,判断是否被吃的话,就判断i与j+N是否是同一类,否则就把i,j+N,i+N,j+2*N,以此类推
    const int maxm = 50005;
    
    int fa[maxm*3], N, K;
    
    void init() {
        memset(fa, -1, sizeof(fa));
    }
    
    int Find(int x) {
        if(fa[x] == -1)
            return x;
        return fa[x] = Find(fa[x]);
    }
    
    void Union(int x, int y) {
        x = Find(x), y = Find(y);
        if(x != y) fa[x] = y;
    }
    
    bool same(int x, int y) {
        return Find(x) == Find(y);
    }
    
    int getnum(int x) {
        return (x + 3*N) %(3*N);
    }
    
    int main() {
        init();
        scanf("%d%d", &N, &K);
        int ans = 0, type, t1, t2;
        for(int i = 0; i < K; ++i) {
            scanf("%d%d%d", &type, &t1, &t2);
            if(t1 > N || t2 > N || t1 < 1 || t2 < 1) {
                ans++;
                continue;
            }
            if(type == 1) {
                if(same(t1, getnum(t2+N)) || same(t1, getnum(t2+2*N))) {
                    ans++;
                } else {
                    Union(t1, t2), Union(getnum(t1+N),getnum(t2+N)), Union(getnum(t1+2*N), getnum(t2+2*N));
                }
            } else if(type == 2) {
                if(same(t1, t2) || same(t1, getnum(t2+2*N))) {
                    ans++;
                } else {
                    Union(t1, getnum(t2+N)), Union(getnum(t1+N), getnum(t2+2*N)), Union(getnum(t1+2*N), t2);
                }
            }
        }
        printf("%d
    ", ans);
        return 0;
    }
    View Code
    
    
  • 相关阅读:
    一起谈.NET技术,C#调试心经(续) 狼人:
    基于xmpp openfire smack开发之openfire介绍和部署[1]
    mysql学习笔记二
    使用jQuery实现的网页版的个人简历
    基于xmpp openfire smack开发之smack类库介绍和使用[2]
    基于色彩恒常( color constancy)特性的FrankleMcCann Retinex图像增强。
    The import org.cocos2dx.lib cannot be resolved
    C++编译器的递归深度与程序优化思考
    jquery实战视频教程_选项卡效果一
    编译器是怎样工作的?用lex和yacc 写一个计算器(2)
  • 原文地址:https://www.cnblogs.com/GRedComeT/p/12182323.html
Copyright © 2011-2022 走看看