Official
E - Make Them Narrow Editorial
by
E - Make Them Narrow Editorial
by
physics0523
\(A\) の要素のうち \(K\) 個消すという操作は、 \(A\) の要素のうち \(N-K\) 個残して \(B\) とすると言い換えられます。
このもとで、 ( \(B\) の最小値 ) となる要素をひとつ決め打つことを考えてみましょう。これを \(A_x\) とします。
( \(B\) の最大値 ) \(-\) ( \(B\) の最小値 ) をなるべく小さくするには、 \(A\) の要素であって \(A_x\) 以上のものを小さい方から \(N-K\) 個残すのが最善です。
このことは、 \(A\) を昇順にソートして連続する \(N-K\) 個を残すのが最善であると言い換えることができます。
このもとで、以下の解法が成立します。
- まず、 \(A_1 \le A_2 \le \dots \le A_N\) を満たすように \(A\) をソートする。
- このとき、 \(A_{l+(N-K)-1}-A_l\) のうち \(1 \le l \le K+1\) での最小値が答えである。
- \(A_l\) を ( \(B\) の最小値 ) と決め打って、連続する \(N-K\) 個の要素を残す場合に対応します。
これは、ソートと for ループを用いることで実装できます。全体で時間計算量 \(O(N \log N)\) です。
実装例 (C++):
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,k;
cin >> n >> k;
vector<int> a(n);
for(auto &nx : a){cin >> nx;}
sort(a.begin(),a.end());
int res=2e9;
for(int i=0;i<=k;i++){
res=min(res,a[i+(n-k)-1]-a[i]);
}
cout << res << "\n";
return 0;
}
posted:
last update: