https://www.luogu.com.cn/problem/P1678
計算機競賽小組的神牛V神終於結束了萬惡的高考,然而作爲班長的他還不能閒下來,班主任老t給了他一個艱鉅的任務:幫同學找出最合理的大學填報方案。可是v神太忙了,身後還有一羣小姑娘等着和他約會,於是他想到了同爲計算機競賽小組的你,請你幫他完成這個艱鉅的任務。
題目描述
現有 m(m\le100000)m(m≤100000) 所學校,每所學校預計分數線是 a_i(a_i\le10^6)ai(ai≤106)。有 n(n\le100000)n(n≤100000) 位學生,估分分別爲 b_i(b_i\le10^6)bi(bi≤106)。
根據n位學生的估分情況,分別給每位學生推薦一所學校,要求學校的預計分數線和學生的估分相差最小(可高可低,畢竟是估分嘛),這個最小值爲不滿意度。求所有學生不滿意度和的最小值。
輸入格式
第一行讀入兩個整數m,n。m表示學校數,n表示學生數。第二行共有m個數,表示m個學校的預計錄取分數。第三行有n個數,表示n個學生的估分成績。
輸出格式
一行,爲最小的不滿度之和。
輸入輸出樣例
輸入 #1複製
4 3 513 598 567 689 500 600 550
輸出 #1複製
32
說明/提示
數據範圍:
對於30%的數據,m,n<=1000,估分和錄取線<=10000;
對於100%的數據,n,m<=100,000,錄取線<=1000000。
思路:枚舉每個學生找絕對值最近的學校分數線,提前sort二分查,找一個<=x的,一個>=x的,再比較。注意一下二分找不到的時候的邊界問題
#include<iostream>
#include<vector>
#include<queue>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e5+10;
typedef long long LL;
LL sch[maxn];
LL stu[maxn];
LL bsearch1(LL l,LL r,LL q)
{
while(l<r)
{
LL mid=(l+r)>>1;
if(sch[mid]>=q) r=mid;
else l=mid+1;
}
return l;
}
LL bsearch2(LL l,LL r,LL q)
{
while(l<r)
{
LL mid=(l+r+1)>>1;
if(sch[mid]<=q) l=mid;
else r=mid-1;
}
return l;
}
int main(void)
{
cin.tie(0);std::ios::sync_with_stdio(false);
LL m,n;cin>>m>>n;
for(LL i=1;i<=m;i++) cin>>sch[i];
for(LL i=1;i<=n;i++) cin>>stu[i];
sort(sch+1,sch+1+m);sort(stu+1,stu+1+n);
LL sum=0;
for(LL i=1;i<=n;i++)
{
LL t1=bsearch1(1,m+1,stu[i]);
LL t2=bsearch2(0,m,stu[i]);
if(t1==m+1) t1=m;
if(t2==0) t2=1;
LL t=min(fabs(stu[i]-sch[t1]),fabs(stu[i]-sch[t2]));
sum+=t;
}
cout<<sum<<endl;
return 0;
}