-
求
的最小值,当
等于
的中位数时,
取得最小值。即将
升序排列后,
显然只与总坐标有关,即求
,将
升序排列后,当
时值最小
总代码:
题目二:https://www.luogu.com.cn/problem/P1632
由中位数定理可知如果将所有点移动到某点
满足最小距离,则
,其中
,意思是
一定是某一点的横左边以及某一点的纵左边,不一定是同一点,那么我就可以全部枚举横纵坐标:
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define HelloWorld IOS;
void solve(){
int n; cin >> n;
vector<int> a(n + 10);
for(int i = 1; i <= n; i ++){
cin >> a[i] >> a[i];
}
sort(a.begin() + 1, a.begin() + 1 + n);
int ans = 0;
for(int i = 1; i <= n; i ++){
ans += abs(a[i] - a[(n + 1) / 2]);
}
cout << ans << endl;
return ;
}
signed main(){
HelloWorld;
int tt = 1;
while(tt --) solve();
return 0;
}
题目二:https://www.luogu.com.cn/problem/P1632
由中位数定理可知如果将所有点移动到某点
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define HelloWorld IOS;
const int inf = 1000000000000000000;
void solve(){
int n; cin >> n;
vector<int> x(n + 10), y(n + 10);
for(int i = 1; i <= n; i ++) cin >> x[i] >> y[i];
vector<int> pre(n + 10, inf);
for(int i = 1; i <= n; i ++){
for(int j = 1; j <= n; j ++){
vector<int> dis;
for(int k = 1; k <= n; k ++) dis.push_back(abs(x[k] - x[i]) + abs(y[k] - y[j]));
sort(dis.begin(), dis.end());
for(int i = 1; i < n; i ++) dis[i] += dis[i - 1];
for(int i = 0; i < n; i ++) pre[i] = min(pre[i], dis[i]);
}
}
for(int i = 0; i < n; i ++) cout << pre[i] << endl;
return ;
}
signed main(){
HelloWorld;
int tt = 1;
while(tt --) solve();
return 0;
}
题目三:https://www.luogu.com.cn/problem/P1889
-
观察纵坐标,因为最终纵坐标一样,所以就是普通的中位数定理,即求
-
再看横坐标,求
的最小值,即求
的最小值,这也可以使用中位数定理,令
,那么求
,首先对
从升序排序,然后依次减去
,满足“小减去小,大减去大”,这样使得整个序列趋向均匀,最后用中位数定理即可
总代码:
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define HelloWorld IOS;
void solve(){
int n; cin >> n;
vector<int> x(n + 10), y(n + 10);
for(int i = 1; i <= n; i ++) cin >> x[i] >> y[i];
sort(x.begin() + 1, x.begin() + 1 + n);
sort(y.begin() + 1, y.begin() + 1 + n);
int ans = 0;
for(int i = 1; i <= n; i ++){
x[i] -= (i - 1);
ans += abs(y[(n + 1) / 2] - y[i]);
}
sort(x.begin() + 1, x.begin() + 1 + n);
for(int i = 1; i <= n; i ++) ans += abs(x[(n + 1) / 2] - x[i]);
cout << ans << endl;
return ;
}
signed main(){
HelloWorld;
int tt = 1;
while(tt --) solve();
return 0;
}



京公网安备 11010502036488号