B - Weird Sum
作者:互联网
题意
计算相同数字单元格之间的距离总和
距离=abs(x1-x2)+abs(y1-y2)
思路
暴力遍历会超时不予考虑
尝试找到答案与整体坐标的关系,最后可以推出一个公式。
两个相同颜色单元格的距离 即 横坐标之差 加 纵坐标之差,那么在颜色相同的单元格中:
任意两个单元格的距离之和 = 任意两个单元格的横坐标差之和 + 这两个单元格的纵坐标差之和。
我们可以分开计算横、纵坐标差之和。
横坐标差之和:
将横坐标升序排列,遍历所有坐标,第 i 个坐标与前面所有坐标差之和为
xi * (i-1) - (x1+x2+x3+… …+xi-1);
例如 i == 1时,第1个坐标与前面所有坐标差之和为:x1 * 0 - 0
i == 2时为:x2 * 1 - (x1)
i == 3时为:x3 * 2 - (x1 + x2)
i == 4时为:x4 * 3 - (x1 + x2 + x3)
上述各式之和即为 任意两个相同颜色单元格横坐标之和。
纵坐标同理。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100002;
vector<ll> q1[N];
vector<ll> q2[N];
int main()
{
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
{
ll a;
cin >> a;
q1[a].push_back(i);
q2[a].push_back(j);
}
ll k = 0;
for (int i = 1; i <= 100000; i++)
{
int t = q1[i].size();
if (t == 0)
continue;
sort(q1[i].begin(), q1[i].end());
sort(q2[i].begin(), q2[i].end());
for (int j = 0; j < t; j++)
{
k += q1[i][j] * (t - j - 1);
k -= q1[i][j] * j;
k += q2[i][j] * (t - j - 1);
k -= q2[i][j] * j;
}
}
cout << abs(k)<< endl;
return 0;
}
标签:int,Sum,单元格,横坐标,坐标,x2,Weird,x1 来源: https://www.cnblogs.com/gosick-ll/p/16098664.html