codeforces1648A(快速求曼哈顿距离)
Problem - A - Codeforces
解题思路
两点的曼哈顿距离可以把所有横纵坐标拆开分成两组,那么就将问题转换成了求数组中所有数对差值的总和,然后对两组从小到大排序
如图,红色的部分就是多出来的数和前面的数的差值,这个值就是最大的数×总个数-所有数的和,如此类推,就可以以O(n)的复杂度算出就结果
代码
#include<bits/stdc++.h>
#define all(x) x.begin(),x.end()
#define int long long
#define endl "\n"
using namespace std;
void solve(){
int n,m;
cin>>n>>m;
map<int,vector<int>>mx,my;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
int t;
cin>>t;
mx[t].push_back(i);
my[t].push_back(j);
}
}
int ans=0;
for(auto &i:mx){
sort(all(i.second));
int s,c;
s=c=1;
s=0;
for(auto j:i.second){
s+=j;
ans+=(c*j-s);
c++;
}
}
for(auto &i:my){
sort(all(i.second));
int s,c;
s=c=1;
s=0;
for(auto j:i.second){
s+=j;
ans+=(c*j-s);
c++;
}
}
cout<<ans<<endl;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int test=1;
while(test--){
solve();
}
return 0;
}