其他分享
首页 > 其他分享> > B - Weird Sum

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