Wired Sum
Wired Sum
题目描述
给定以一个 n * m 的矩阵,矩阵每个元素的数值代表颜色,求相同颜色元素的曼哈顿距离
解题思路
让求所有相同颜色的曼哈顿距离,对于求某一种颜色的距离,可以分成两步,第一步求出相同颜色的,延 x 轴方向上的距离,第二步求延 y 轴方向上的距离,然后相加,其他颜色亦是如此。以求延 x 轴方向上的距离为例(y轴同理),把所有点的横坐标从小到大排序,
求 之前的点到 的距离s(若下标从0开始),则有 s = j * - ( + + ... + ),后者刚好是前 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 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步