[关闭]
@PanMingjun 2018-09-13T12:19:56.000000Z 字数 2292 阅读 650

CS Academy-Manhattan Distances


[题目链接]

大意:
二维平面给n个点,在x轴上找一个点使它到离它最近的k个点的曼哈顿距离之和最小

个人题解:
先看问题的简化版,在一维平面(比如x轴)上给个点,找一个点使它到所有点的距离之和最小,设满足条件的点为易证

考虑二维情况下,如果我们选定的点为,记离它最近的k个点构成的集合为,则集合中所有点的曼哈顿距离之和为



然后大胆猜结论(此题解请勿扩散!!!!)

在二维情况下在x轴上选点和一维同理,最小值一定在某个满足有个点且有个点满足,易得,然后对每个求出它左边有个点和右边有个点的情况加一下取个


  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <algorithm>
  5. #include <string.h>
  6. #include <math.h>
  7. #include <vector>
  8. #include <set>
  9. #include <map>
  10. #include <queue>
  11. #include <stack>
  12. #define mem(a,b) memset(a,b,sizeof(a))
  13. #define ll long long
  14. #define ull unsigned long long
  15. #define EPS 1e-8
  16. #define IOS ios_base::sync_with_stdio(0); cin.tie(0)
  17. #define endl '\n'
  18. using namespace std;
  19. typedef pair<int,int> pii;
  20. typedef pair<long long,long long> pll;
  21. const double pi = acos(-1.0);
  22. inline ll read()
  23. {
  24. ll x=0,f=1;char ch=getchar();
  25. while (ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();}
  26. while (ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
  27. return f*x;
  28. }
  29. void write(ll a){
  30. if (a<0) putchar('-'),a=-a;
  31. if (a>=10) write(a/10); putchar(a%10+'0');
  32. }
  33. const ll INF=1e18;
  34. void solve(vector<pll>& p,vector<ll> &ans,ll num,bool flag){
  35. priority_queue<ll> pq;
  36. ll sum=0;
  37. for(auto& ite:p){
  38. ll x=ite.first,y=ite.second;
  39. if(flag){
  40. if((int)pq.size()==num){
  41. ans.push_back(num*x+sum);
  42. }else{
  43. ans.push_back(INF);
  44. }
  45. }
  46. sum+=y-x;
  47. pq.push(y-x);
  48. while((int)pq.size()>num){
  49. sum-=pq.top();
  50. pq.pop();
  51. }
  52. if(!flag){
  53. if((int)pq.size()==num){
  54. ans.push_back(num*x+sum);
  55. }else{
  56. ans.push_back(INF);
  57. }
  58. }
  59. }
  60. }
  61. int main()
  62. {
  63. #ifdef TEST
  64. freopen("input.txt","r",stdin);
  65. #endif
  66. ll n,k;
  67. cin>>n>>k;
  68. vector<pll> points(n);
  69. for(auto&ite :points){
  70. cin>>ite.first>>ite.second;
  71. }
  72. sort(points.begin(),points.end());
  73. vector<ll> left,right;
  74. solve(points,left,k>>1,true);
  75. reverse(points.begin(),points.end());
  76. for(auto &ite:points){
  77. ite.first*=-1;
  78. }
  79. solve(points,right,k-(k>>1),false);
  80. reverse(right.begin(),right.end());
  81. ll ans=INF;
  82. for(int i=0;i<n;i++){
  83. ans=min(ans,left[i]+right[i]);
  84. }
  85. cout<<(ans==INF?points[0].second:ans)<<endl;
  86. return 0;
  87. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注