无专精则|

伍六柒-

园龄:3年6个月粉丝:9关注:6

Wired Sum

Wired Sum

题目描述
给定以一个 n * m 的矩阵,矩阵每个元素的数值代表颜色,求相同颜色元素的曼哈顿距离

题目链接


解题思路

让求所有相同颜色的曼哈顿距离,对于求某一种颜色的距离,可以分成两步,第一步求出相同颜色的,延 x 轴方向上的距离,第二步求延 y 轴方向上的距离,然后相加,其他颜色亦是如此。以求延 x 轴方向上的距离为例(y轴同理),把所有点的横坐标从小到大排序,

图片

xj 之前的点到 xj 的距离s(若下标从0开始),则有 s = j * xj - (x0 + x1 + ... + xj1),后者刚好是前 j-1 项的和,其次就是存颜色,在这里用vector存储,因为只知道 n * m的范围,所以不能直接开辟数组空间,vector初始开辟空间为 0。

代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#define int long long
#define endl '\n'
using namespace std;
const int N = 1e5 + 10;
typedef pair<int, int> PII;
vector<int> x[N], y[N]; //x[i][j] 表示第 j 个颜色为 i 的点出现的行号,同理 y 表示列号
int t, n, m;
void solve() {
int ans = 0;
cin >> n >> m;
vector<vector<int>> g(n + 1, vector<int> (m + 1)); //用来存储颜色
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++){
cin >> g[i][j];
x[g[i][j]].push_back(i);
y[g[i][j]].push_back(j);
}
for(int i = 1; i <= 1e5; i++) {
sort(x[i].begin(), x[i].end());
int sum = 0; // sum 记录前缀和
for(int j = 0; j < x[i].size(); j++) {
ans += j * x[i][j] - sum;
sum += x[i][j];
}
sort(y[i].begin(), y[i].end());
sum = 0;
for(int j = 0; j < y[i].size(); j++) {
ans += j * y[i][j] - sum;
sum += y[i][j];
}
}
cout << ans << endl;
}
signed main() {r
solve();
return 0;
}

本文作者:伍六柒-

本文链接:https://www.cnblogs.com/paper-plane/p/16003852.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   伍六柒-  阅读(26)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开