問題の説明
XiaomingCompanyのオフィスエリアには、下の図に示すように、N個の正方形のエリアで構成される長い廊下があります。
ロボットを掃引Kは、i番目がAであるの廊下に配備されているI-番目のグリッド領域。
掃引ロボットは毎分左右の隣接するマス目に移動し、そのエリアを掃除できることが知られています。
各ロボットの清掃ルートを計算するプログラムを作成して、次のようにしてください。
- 彼らは皆、最終的に出発広場に戻ります、
- すべての正方形の領域は、少なくとも1回はクリーニングされています。
- ロボットの動作開始から最後のロボットの復帰までの時間は最短です。
複数のロボットが同時に同じ正方形の領域を掃除することができ、それらが互いに影響を与えることはないことに注意してください。
出力にかかる最小時間。
上の図に示されている例では、費やされる最小時間は6です。
- 最初のルート:2-1-2-3-4-3-2、エリア1、2、3、および4が清掃されました。
- 2番目のルート:5-6-7-6-5、5、6、および7がクリーニングされました。
- 3番目のルート:10-9-8-9-10、8、9、10をクリーニング。
入力形式
最初の行には、2つの整数NとKが含まれています。
次のK行では、各行に整数Aiがあります。
出力形式
答えを表す整数を出力します。
サンプル入力
10 3
5
2
10
サンプル出力
6
データ範囲
評価ユースケースの30%で、1≤K<N≤10。
評価のユースケースの60%で、1≤K<N≤1000。
すべての評価のユースケースのために、1≤K <N≤100000、および1≤A I ≤N.
問題解決
2つのポイント:
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int n, k;
int p[N];
bool check(int x)
{
int R = 0; // R 表示机器人已经扫到的区域右边界
for (int i = 0; i < k; i ++)
{
if(p[i] - x > R) return false; // 不能无缝衔接扫地区域,则一定失败
else
{
if(p[i] <= R) R = p[i] + x - 1; // 在区域内,则从本区域开始,能扫到的最远区域
else R += x; // 在区域外,则直接从边界累加
}
}
return R >= n; // 判断是否能扫完整个区域
}
int main()
{
cin >> n >> k;
for (int i = 0; i < k; i ++) cin >> p[i];
sort(p, p + k);
int l = 0, r = n;
while(l < r)
{
int mid = l + r >> 1; // 二分机器人的扫地范围
if(check(mid)) r = mid;
else l = mid + 1;
}
cout << 2 * l - 2 << endl; // 花费时间 = 2 × (扫地范围 - 1)
return 0;
}
ps:花费时间 = 2 × (扫地范围 - 1)
この文章がわからない場合は、絵を描いてシミュレートできます。