• I


    约翰和他的邻居生活在一个村庄里,他们的道路修建的很特别,都是正东正西或者正南正北,但是呢他们用一种方式描述他们和邻居的位置,比如说 6号 在1号 东面13处,那么我们就可以计算出来这两家的曼哈顿距离,也就是|x-x1| + |y-y1|, 当然这是让我们来求距离的.....
    这个约翰也是比较特殊,他会一秒说出来一条道路的位置,当然在说的时候也会有一些查询,查询也是比较特别的,就是给三个参数,第一个第二个是描述的位置,第三个是时间,就是问前这些时间能不能算出他们的距离是多少?不能的话输出 -1 ,能的话输出曼哈顿距离。
    分析:首先看这题想的是建立一个坐标系,让根节点是 0 0,然后可以计算根节点和他们之间的距离,不过这样的办法很难区间合并,所以pass,又想了一个办法,直接记录东西南北四个方向的位置,比方说A在B的东20,西40,这样就可以解决合并问题了,只需要把父节点的值加上也可以更新了。
    ////////////////////////////////////////////////////////+
    竟然一下就对了........幸福来得太突然
    #include<iostream>
    #include<algorithm>
    #include<stdio.h>
    #include<math.h>
    #include<string.h>
    #include<queue>
    #include<stack>
    using namespace std;

    const int maxn = 40005;

    int f[maxn];
    struct Point{int E, N;}val[maxn];//记录相对位置
    struct node{int u, v, len, op;}data[maxn];
    int dir[4] = {1, -1, -11};//代表东西南北

    int Find(int x)
    {
        int k = f[x];
        if(f[x] != x)
        {
            f[x] = Find(f[x]);
            val[x].E += val[k].E;
            val[x].N += val[k].N;
        }

        return f[x];
    }
    void Union(int u, int v, int len, int op)
    {
        int ru = Find(u), rv = Find(v);

        if(ru != rv)
        {
            f[rv] = ru;//别倒着写,因为有方向是B在A的位置
            val[rv].E = -val[v].E + val[u].E + len * dir[op] * (op < 2 ? 1 : 0);
            val[rv].N = -val[v].N + val[u].N + len * dir[op] * (op > 1 ? 1 : 0);
        }
    }

    int main()
    {
        int i, N, M;

        while(scanf("%d%d", &N, &M) != EOF)
        {
            char s[10];

            for(i=1; i<=N; i++)
            {
                f[i] = i;
                val[i].E = val[i].N = 0;
            }

            for(i=1; i<=M; i++)
            {
                scanf("%d%d%d%s", &data[i].u, &data[i].v, &data[i].len, s);
                if(s[0] == 'E')
                    data[i].op = 0;
                else if(s[0] == 'W')
                    data[i].op = 1;
                else if(s[0] == 'S')
                    data[i].op = 2;
                else
                    data[i].op = 3;
            }

            int Q, u, v, ru, rv;

            scanf("%d", &Q);

            i = 1;
            while(Q--)
            {
                scanf("%d%d%d", &u, &v, &M);

                while(i <= M)
                {
                    Union(data[i].u, data[i].v, data[i].len, data[i].op);
                    i++;
                }

                ru = Find(u), rv = Find(v);

                if(ru != rv)
                    printf("-1 ");
                else
                {
                    int ans = (int)(fabs(val[u].E-val[v].E) + fabs(val[u].N-val[v].N));
                    printf("%d ", ans);
                }
            }
        }

        return 0;

    } 

  • 相关阅读:
    设计模式学习之路——Strategy 策略模式
    C# 异步编程 结束异步调用
    设计模式学习之路——Chain Of Responsibility 职责链模式
    delphi笔记之XML操作
    AS3判断XML属性是否存在
    Loader ,URLLoader ,URLStream的使用区别(转)
    delphi笔记之nativeXml
    Delphi的颜色转换
    Delphi利用Bass.dll播放音频
    【转】球坐标旋转
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4672814.html
Copyright © 2020-2023  润新知