zoukankan      html  css  js  c++  java
  • XXI Open Cup. Grand Prix of Korea J. Remote Control 相对位置 启发式合并

    XXI Open Cup. Grand Prix of Korea J. Remote Control 相对位置 启发式合并

    题意

    给定长度为(N)的包括上下左右的操作序列,在((0,0))点有一障碍物

    需要回答(Q)个询问,表示从某个起点开始,按照操作序列移动到达的最终位置,若移动到了障碍物,则撤销此次操作

    [1 leq N leq 3 imes10^5\ 1 leq Q leq 3 imes10^5\ -3 imes10^5 leq x,y leq 3 imes10^5 ]

    分析

    最终位置实际上是相对于障碍物的相对位置,因此我们只关注相对位置,不难想到把移动物体变换成移动障碍物,最终障碍物所在的位置就可以确定所有询问的最终位置

    离线处理出所有询问,考虑如果障碍物碰到某个询问,显然我们不能让障碍物停下(这样其他询问就会出问题),由于我们只关注相对位置,相当于询问向冲突的方向移动一单位。由于可能某个单位有多个询问,需要对受影响的两个位置合并,因此考虑启发式合并。复杂度(O(nlogn))

    代码

    实现时可以使用vector,但是需要注意用指针来(O(1)) 寻址

    #include<bits/stdc++.h>
    #define pii pair<int,int>
    #define fi first
    #define se second
    using namespace std;
    typedef long long ll;
    typedef vector<int> VI;
    inline ll rd(){
        ll x;
        scanf("%lld",&x);
        return x;
    }
    
    map<char,int> dx = {{'R',-1},{'L',1}};
    map<char,int> dy = {{'U',-1},{'D',1}};
    
    map<pii,VI*> s;
    
    inline void merge(pii a,pii b){
        vector<int>* v1 = s[a];
        vector<int>* v2 = s[b];
        if(v1 -> size() > v2 -> size()) {
            v1 -> insert(v1 -> end(),v2 -> begin(),v2 -> end());
            v2 -> clear();
            s[b] = v1;
        }
        else {
            v2 -> insert(v2 -> end(),v1 -> begin(),v1 -> end());
            v1 -> clear();
        }
        s.erase(a);
    }
    
    int main(){
        cin.tie(NULL);
        ios_base::sync_with_stdio(false);
        int n;
        cin >> n;
        string ss;
        cin >> ss;
        int q;
        cin >> q;
        for(int i = 0; i < q;i++){
            int x,y;
            cin >> x >> y;
            if(!s.count(make_pair(x,y))) s[make_pair(x,y)] = new VI;
            s[make_pair(x,y)] -> push_back(i);
        }
        int x = 0,y = 0;
        for(auto c:ss){
            int x3 = x + dx[c];
            int y3 = y + dy[c];
            int x4 = x + 2 * dx[c];
            int y4 = y + 2 * dy[c];
            if(s.count(make_pair(x3,y3))) {
                if(s.count(make_pair(x4,y4))) merge(make_pair(x3,y3),make_pair(x4,y4));
                else s[make_pair(x4,y4)] = s[make_pair(x3,y3)],s.erase(make_pair(x3,y3));
            }
            x = x3;
            y = y3;
        }
        vector<pii> ans(q);
        for(auto it:s){
            auto b = it.fi;
            int bx = b.fi;
            int by = b.se;
            VI tmp = *it.se;
            for(auto itt:tmp) ans[itt] = make_pair(bx - x,by - y);
        }
        for(auto it:ans){
            cout << it.fi << ' ' << it.se << '
    ';
        }
    }
    
  • 相关阅读:
    JavaScript根据CSS的Media Queries来判断浏览设备的方法
    JavaScript API 设计原则
    高性能 CSS3 动画
    CSS代码实例:用CSS代码写出的各种形状图形
    frontpage 2010.2003绿色版
    Web前端年后跳槽必看的各种面试题
    [ksm][数学] Jzoj P5810 简单的玄学
    [分治] Jzoj P5807 简单的区间
    [dfs][bfs] Jzoj P5806 简单的操作
    [dp] Jzoj P5804 简单的序列
  • 原文地址:https://www.cnblogs.com/hznumqf/p/15457576.html
Copyright © 2011-2022 走看看