LuoguP3964 [TJOI2013]松鼠聚会【切比雪夫距离/前缀和】

 

题目传送门

前置知识:切比雪夫距离和曼哈顿距离的相互转化--自为风月马前卒

有了这个知识,我们便可以在读入松鼠的家的坐标时,先把他转化一下,然后把最后的总式化简,我们会得到一个充满后缀和以及前缀和的式子,这里有十分详细的展开式。于是我们把$x$,$y$坐标分别排序并求出他们的前缀和即可。

之后我们枚举每个点,在这个点意义下求出答案,更新答案最小值。

Code

 1 #include<cstdio>
 2 #include<algorithm>
 3 
 4 using namespace std;
 5 typedef long long ll;
 6 
 7 int n;
 8 ll tmp,ans=1e16;
 9 ll subx[100090],suby[100090];
10 ll rx[100090],ry[100090];
11 struct node{
12     ll x,y;
13 }p[100090];
14 
15 ll check(int u)
16 {
17     int pos=0;
18     ll ax=0,ay=0;
19     pos=lower_bound(rx+1,rx+1+n,p[u].x)-rx;
20     ax+=pos*p[u].x-subx[pos];
21     ax+=subx[n]-subx[pos]-p[u].x*(n-pos);
22     pos=lower_bound(ry+1,ry+1+n,p[u].y)-ry;
23     ay+=pos*p[u].y-suby[pos];
24     ay+=suby[n]-suby[pos]-p[u].y*(n-pos);
25     return ax+ay;
26 }
27 
28 int main()
29 {
30     scanf("%d",&n);
31     for(int i=1;i<=n;i++)
32     {
33         ll x=0,y=0;
34         scanf("%lld%lld",&x,&y);
35         rx[i]=x+y;ry[i]=x-y;
36         p[i].x=rx[i],p[i].y=ry[i];
37     }
38     sort(rx+1,rx+1+n);
39     sort(ry+1,ry+1+n);
40     for(int i=1;i<=n;i++)
41         subx[i]=subx[i-1]+rx[i],suby[i]=suby[i-1]+ry[i];
42     for(int i=1;i<=n;i++)
43         tmp=check(i),ans=min(ans,tmp);
44     printf("%lld",ans>>1);
45     return 0;
46 }
View Code

* 注意观察式子,在前缀和那里不要用错=w=...

 1 #include<cstdio>
 2 #include<algorithm>
 3 
 4 using namespace std;
 5 typedef long long ll;
 6 
 7 int n;
 8 ll tmp,ans=1e16;
 9 ll subx[100090],suby[100090];
10 ll rx[100090],ry[100090];
11 struct node{
12     ll x,y;
13 }p[100090];
14 
15 ll check(int u)
16 {
17     int pos=0;
18     ll ax=0,ay=0;
19     pos=lower_bound(rx+1,rx+1+n,p[u].x)-rx;
20     ax+=pos*p[u].x-subx[pos];
21     ax+=subx[n]-subx[pos-1]-p[u].x*(n-pos);
22     pos=lower_bound(ry+1,ry+1+n,p[u].y)-ry;
23     ay+=pos*p[u].y-suby[pos];
24     ay+=suby[n]-suby[pos-1]-p[u].y*(n-pos);
25     return ax+ay;
26 }
27 
28 int main()
29 {
30     scanf("%d",&n);
31     for(int i=1;i<=n;i++)
32     {
33         ll x=0,y=0;
34         scanf("%lld%lld",&x,&y);
35         rx[i]=x+y;ry[i]=x-y;
36         p[i].x=rx[i],p[i].y=ry[i];
37     }
38     sort(rx+1,rx+1+n);
39     sort(ry+1,ry+1+n);
40     for(int i=1;i<=n;i++)
41         subx[i]=subx[i-1]+rx[i],suby[i]=suby[i-1]+ry[i];
42     for(int i=1;i<=n;i++)
43         tmp=check(i),ans=min(ans,tmp);
44     printf("%lld",ans>>1);
45     return 0;
46 }
WA

 

转载于:https://www.cnblogs.com/nopartyfoucaodong/p/9770388.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值