• hdu4829 带权并查集(题目不错)


    题意:


    Information

    Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 275 Accepted Submission(s): 33


    Problem Description
    军情紧急,我们需要立刻开发出一个程序去处理前线侦察兵发回的情报,并做出相应的分析。现在由你负责其中的一个子模块,你需要根据情报计算出敌方坦克的位置。
    当敌方坦克静止时,侦察兵会尽力估算出它们之间的位置,而每当敌方坦克移动时,侦察兵都会记录下坦克新的位置并向你报告。每个坦克的位置可以由一个二维整数坐标来描述。
    前线发回的情报有四种格式:
    1 A B X Y
    表示A坦克移动到了与B坦克的相对位置是(X,Y)的地方,即XA = XB + X, YA=YB+Y。
    2 A X Y
    表示A坦克移动到了绝对位置是(X,Y)的地方,即XA = X, YA = Y。
    3 A B X Y
    表示发现了A坦克与B坦克的相对位置是(X,Y),即XA = XB + X, YA=YB+Y。
    4 A X Y
    表示发现了A坦克的绝对位置是(X,Y),即XA = X, YA = Y。
    我们需要你对于如下两种询问及时做出回应:
    5 A B
    表示询问A坦克与B坦克的相对位置是多少,即分别求出XA - XB 以及YA -YB
    6 A
    表示询问A坦克的绝对位置是多少,即求出XA 和YA
    其中A和B代表的是任意的一个坦克的编号,(X,Y)表示了坦克的二维坐标。你可以假设初始时刻我们对于敌方任何坦克的位置都一无所知,在此之后坦克的每一次移动都被侦察兵侦察到了。
    请注意两个坦克的坐标有可能相同。

    Input
    输入的第一行是一个整数T(T < 1000),表示共有T组数据。
    对于每组数据,第一行有一个整数N,表示这组数据有N次查询。接下来的每行表示一次查询,每次查询第一个数字代表是哪种询问,询问的格式详见上文。
    数据范围:
    0 < N <=100000, 0<A,B<=N 且 A<>B, X和Y都是整数且 0 <=X,Y<=10000 .
    测试数据中98%的数据N不超过50。

    Output
    对于每组数据,首先需要输出单独一行”Case #?:”,其中问号处应填入当前的数据组数,组数从1开始计算。
    对于每一个类型(1)或者(2)的询问,请把它们加入到你的记录中。
    对于每一个类型(3)或者(4)的询问,如果与之前记录的内容有矛盾,请输出”REJECT”并将这个情报忽略掉,如没有矛盾,请把它们加入到你的记录中。
    对于每一个类型(5)或者(6)的询问,如果根据之前的记录能推出结论,请输出两个整数X和Y,两个整数之间有一个空格;如果不能推出结论,请输出”UNKNOWN”。输出的所有信息都不包括引号。

    Sample Input
    2 7 1 1 2 3 4 2 3 4 5 3 4 5 2 1 4 6 2 2 3 2 4 6 2 5 4 1 6 3 6 6 3 4 3 2 2 6 3 2 4 2 3 5 3 4 3 3 4 1 2

    Sample Output
    Case #1: -9 -6 4 5 Case #2: UNKNOWN 2 2 0 -1 REJECT

    思路:
           这个题目做了好久了,各种纠结,原因是自己吧自己绕道圈子里面了,越绕越复杂
    ,看到这个题目直接就想到带权并查集,这个毫无疑问,同时还想到1,2都是创建先的节点,但关键是在hash节点和判断当前这个集合时候是已知点的时候sb了,后来蒙了,当时我是标记父亲节点,每次要是有个点是已知的,那么就直接吧他的当前父亲节点标记上,结果各种wa,就这样不知wa了多久,后来看了别人的处理方式,哎!真的是先想好在敲啊,思路直接敲有的时候会死的很惨的啊,对于1,2,是要建立新的节点的,其余的不用,对于已知的点,直接把他父亲连接到0节点上,0节点就表示是已知的(可以是别的自己随意),这样写的时候就简单多了,对于hash点的时候,我是来一个hash一个,不来不用,具体看代码。


    #include<stdio.h>
    
    #define N 200000
    
    int mer[N] ,X[N] ,Y[N] ,hash[N];
    
    int finds(int x)
    {
       if(x == mer[x]) return x;
       int t = mer[x];
       mer[x] = finds(mer[x]);
       X[x] += X[t];
       Y[x] += Y[t];
       return mer[x];
    }
    
    int main ()
    {
       int t ,n ,cas = 1;
       int key ,a ,b ,x ,y;
       scanf("%d" ,&t);
       while(t--)
       {
          scanf("%d" ,&n);
          printf("Case #%d:
    " ,cas ++);
          for(int i = 0 ;i <= n * 2 ;i ++)
          mer[i] = i ,X[i] = Y[i] = 0 ,hash[i] = -1;
          int nown = 0;
          hash[0] = 0;
          while(n--)
          {
             scanf("%d" ,&key);
             if(key == 1 || key == 2)
             {
                if(key == 1) 
                scanf("%d %d %d %d" ,&a ,&b ,&x ,&y);
                else 
                {
                   scanf("%d %d %d" ,&a ,&x ,&y);
                   b = 0;
                }
                hash[a] = ++nown;
                if(hash[b] == -1) hash[b] = ++nown;
                int ra = finds(hash[a]) ,rb = finds(hash[b]);
                mer[ra] = rb;
                X[ra] = X[hash[b]] - X[hash[a]] + x;
                Y[ra] = Y[hash[b]] - Y[hash[a]] + y;
             }
             if(key == 3 || key == 4)
             {
                if(key == 3)
                scanf("%d %d %d %d" ,&a ,&b ,&x ,&y);
                else
                {
                   b = 0;
                   scanf("%d %d %d" ,&a ,&x ,&y);
                }
                if(hash[a] == -1) hash[a] = ++nown;
                if(hash[b] == -1) hash[b] = ++nown;
                int ra = finds(hash[a]) ,rb = finds(hash[b]);
                if(ra == rb)
                {
                   if(X[hash[a]] - X[hash[b]] != x || Y[hash[a]] - Y[hash[b]] != y)
                   printf("REJECT
    ");
                }
                else 
                {
                    mer[ra] = rb;
                    X[ra] = X[hash[b]] - X[hash[a]] + x;
                    Y[ra] = Y[hash[b]] - Y[hash[a]] + y;
                }
             }
             if(key == 5 || key == 6)
             {
                if(key == 5) 
                scanf("%d %d" ,&a ,&b);
                else 
                {
                   scanf("%d" ,&a);
                   b = 0;
                }
                if(hash[a] == -1) hash[a] = ++nown;
                if(hash[b] == -1) hash[b] = ++nown;
                int ra = finds(hash[a]) ,rb = finds(hash[b]);
                if(ra != rb) printf("UNKNOWN
    ");
                else printf("%d %d
    " ,X[hash[a]] - X[hash[b]] ,Y[hash[a]] - Y[hash[b]]);
             }
          }
       }
       return 0;
    }
                
    

     


  • 相关阅读:
    IntelliJ IDEA 14.03 java 中文文本处理中的编码格式设置
    应聘感悟
    STL string分析
    CUDA SDK VolumeRender 分析 (1)
    BSP
    CUDA SDK VolumeRender 分析 (3)
    CUDA SDK VolumeRender 分析 (2)
    Windows软件发布时遇到的一些问题
    Ten Commandments of Egoless Programming (转载)
    复习下光照知识
  • 原文地址:https://www.cnblogs.com/csnd/p/12063027.html
Copyright © 2020-2023  润新知