zoukankan      html  css  js  c++  java
  • 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;
    }
                
    

     


  • 相关阅读:
    UIrecorder脚本录制与回放
    通过jmeter读取csv的case来实现接口自动化
    Jmeter操作MySQL数据库详解
    使用docker安装Jenkins
    CMMS / EAM与工厂其它业务流程的交集,融合趋势有哪些
    如何让CMMS系统适应您的企业
    CMMS系统中的物联监测
    CMMS系统中工单派案&调度
    移动化的设备维护管理系统--移动端界面
    物流行业设备维护管理系统
  • 原文地址:https://www.cnblogs.com/csnd/p/12063026.html
Copyright © 2011-2022 走看看