列表

详情


NC253368. qsgg and Move

描述

平面直角坐标系上有 n 个点,坐标给定,一开始你在原点,即 (0,0)

每次移动,你会移动到离自己 曼哈顿距离 最远且之前没到达过的点

(如果有多个点最远,选择编号最小的点),移动距离即为曼哈顿距离。直到访问完最后一个点,移动结束。

你想知道移动的总距离。
注:在平面上,坐标 (x_1,y_1) 的 i 点与坐标 (x_2,y_2) 的 j 点的曼哈顿距离为: d(i,j)=|x_1-x_2|+|y_1-y_2|.

输入描述

输入共 n+1 行。

第一行一个整数表示 n\ (1≤n≤10^6)

接下来 n 行,每行 2 个整数 x_i,y_i \ (1≤x_i,y_i≤10^9) 表示编号为 i 的坐标 (x_i,y_i)
数据保证不同编号的坐标不相同。

输出描述

输出一个整数,表示移动的总距离。

示例1

输入:

5
8 9
6 4
11 3
13 6
13 9

输出:

60

说明:

移动过程:移动过程如下:
(0,0)\rightarrow(13,9)\rightarrow(6,4)\rightarrow(13,6)\rightarrow(8,9)\rightarrow(11,3)
移动距离分别为22,12,9,8,9,和为 60

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++ 11.0.1) 解法, 执行用时: 1676ms, 内存消耗: 116384K, 提交时间: 2023-06-26 18:23:10

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define P pair<ll,ll>
int main(){
    ll n;cin>>n;
    vector<P>v1;
    for(int i=1;i<=n;i++){
        ll x,y;cin>>x>>y;
        v1.push_back({x,y});
    }
    vector<vector<P>>v2(5);
    for(int i=0;i<v1.size();i++){
       ll x=v1[i].first,y=v1[i].second;
        // -i 是保证曼哈顿 距离相等的 时候 先找到id 较小的数
       v2[0].push_back({x+y,-i});
       v2[1].push_back({x-y,-i});
       v2[2].push_back({-x+y,-i});
       v2[3].push_back({-x-y,-i});
    }
    for(int i=0;i<4;i++){
        sort(v2[i].begin(),v2[i].end());
    }
    bool st[n];
    memset(st,0,sizeof(st));
    ll x1=0,y1=0,ans=0;
    for(int i=1;i<=n;i++){
        ll c=-1,d=-1;
        for(int j=0;j<4;j++){
    
            while(st[-v2[j].back().second]){
                v2[j].pop_back();
            }
            
            ll cj=-v2[j].back().second;
            ll dj=abs(x1-v1[cj].first)+abs(y1-v1[cj].second);
            
            if(dj>d||(dj==d&&cj<c)){
                c=cj;d=dj;
            }
        }
        ans+=d;
        st[c]=1;
        x1=v1[c].first;y1=v1[c].second;
    }
    cout<<ans<<endl;
    return 0;
}

C++(g++ 7.5.0) 解法, 执行用时: 884ms, 内存消耗: 51428K, 提交时间: 2023-06-24 12:38:14

#include <bits/stdc++.h>
using namespace std;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin >> n;
    vector<int> vis(n);
    vector<pair<int, int>> a(n);
    vector p(4, vector<pair<int, int>>(n));
    for (int i = 0; i < n; i++) {
        auto &[x, y] = a[i];
        cin >> x >> y;
        p[0][i] = {x + y, -i};
        p[1][i] = {-x + y, -i};
        p[2][i] = {x - y, -i};
        p[3][i] = {-x - y, -i};
    }
    for (auto &i : p) sort(i.begin(), i.end());
    long long ans = 0, curx = 0, cury = 0;
    for (int i = 0; i < n; i++) {
        int id = 0, td = 0;
        for (int j = 0; j < 4; j++) {
            while (vis[-p[j].back().second]) p[j].pop_back();
            int dd = -p[j].back().second;
            int dis = abs(curx - a[dd].first) + abs(cury - a[dd].second);
            if (dis > td || (dis == td && id > dd)) {
                td = dis; id = dd;
            }
        }
        curx = a[id].first; cury = a[id].second;
        ans += td; vis[id] = 1;
    }
    cout << ans;
    return 0;
}

上一题