公式
B - 荷物の配送センター / Package Distribution Center 解説
by
B - 荷物の配送センター / Package Distribution Center 解説
by
physics0523
印刷ページ
この問題で要求されていることを整理します。
- まず、配送センターは座標 \(S_i\) ( \(1 \le i \le M\) ) に存在する。
- 全ての \(1 \le i \le N\) について、届け先が座標 \(D_i\) にある。この荷物については、 \(D_i\) に最も近い配送センターを見つけてそこから配送すればよい。
「最も近い配送センターを見つける」という点が難しそうです。どのようにすればよいでしょうか?
まず、データ構造を使って、以下の検索をします。
- 座標が \(D_i\) 以上で最小の配送センターの座標 \(r\) を見つける
- 座標が \(D_i\) 未満で最大の配送センターの座標 \(l\) を見つける
このとき、この \(2\) つのどちらかが最寄りの配送センターなので、この荷物については配送コストの最小値は \(\min(r-D_i,D_i-l)\) です。
上記のような検索は、ソート済みの配列から二分探索で行うこともできるほか、 C++ では set を用いると便利です。
実装の都合で、座標 \(\pm \infty\) (十分大きな値) に配送センターを置くと範囲外参照などを防止出来て楽になることがあります。
あとは、各荷物についての最小配送コストを足し合わせればよいです。
実装例 (C++):
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
int main(){
ll n,m;
cin >> n >> m;
vector<ll> d(n);
for(auto &nx : d){cin >> nx;}
set<ll> st;
for(ll i=0;i<m;i++){
ll s;
cin >> s;
st.insert(s);
}
st.insert(-1e18);
st.insert(1e18);
ll res=0;
for(auto &nx : d){
auto it=st.lower_bound(nx);
ll add=(*it)-nx;
it--;
add=min(add,nx-(*it));
res+=add;
}
cout << res << "\n";
return 0;
}
投稿日時:
最終更新:
