APIO2015 T3 Palembang Bridges

这题好玩

首先家和工地在同侧的不用建桥,排掉

然后我们考虑需要建桥的:
∑ i = 1 n D i = ∑ i = 1 n ∣ B − S i ∣ + ∣ B − T i ∣ ⋯ B为桥的位置 \sum_{i=1}^n D_i=\sum_{i=1}^n |B-S_i|+|B-T_i|\cdots\text{B为桥的位置} i=1nDi=i=1nBSi+BTiB为桥的位置

如果把家和工地都放在数轴上的点上
所以桥要建到中位数的位置

  1. 对于k=1, O ( 1 ) O(1) O(1)求出中位数
  2. 对于k=2,由于桥的存在,数轴上的点分裂成两派,每一派走他们的桥
    那么枚这个分裂点,计算两边的最短距离,打擂台得到最小

暴力做法:(5分)

#include<bits/stdc++.h>
#define re register
#define in Read()
using namespace std;
int in{
	int i=0,f=1;char ch;
	while(!isdigit(ch)&&ch!='-')ch=getchar();
	if(ch=='-')ch=getchar(),f=-1;
	while(isdigit(ch))i=(i<<1)+(i<<3)+ch-48,ch=getchar();
	return i*f;
}

const int NNN=2e5+10;
int k,n,cnt/*记录要过桥的距离*/;
char PP[10],QQ[10];
int dot[NNN],tot;
int confirmed_sum;

inline int get_sum(int l,int r,int mid){
	int res=0;
	for(re int i=l;i<=r;++i)
		res+=abs(dot[mid]-dot[i]);
	return res;
}

inline int work1(){
	sort(dot+1,dot+tot+1);
	return min(get_sum(1,tot,(1+n)>>1),get_sum(1,tot,((1+n)>>1)+1));
}

inline int work2(){
	sort(dot+1,dot+tot+1);
	int res=2147483647;
	for(re int i=1;i<=tot;++i){
		res=min(res,min(get_sum(1,i,(1+i)>>1),get_sum(1,i,((1+i)>>1)+1))+
				min(get_sum(i+1,tot,(i+tot+1)>>1),get_sum(i+1,tot,((i+tot+1)>>1)+1)));
	}
	return res;
}

int main(){
	k=in,cnt=n=in;
	for(re int i=1;i<=n;++i){
		scanf("%s",PP);
		int a=in;
		scanf("%s",QQ);
		int b=in;
		if(PP[0]^QQ[0])
			dot[++tot]=a,dot[++tot]=b;
		else confirmed_sum+=abs(a-b),--cnt;
	}
	
	int res=0;
	if(k==1)res=work1();
	if(k==2)res=work2();
	res+=confirmed_sum+cnt;
	
	printf("%d\n",res);
	
	return 0;
}

明显不够
考虑使用数据结构——线段树

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值