Codeforces 702C Cellular Network(二分)

题目链接:http://codeforces.com/problemset/problem/702/C

题意:

  在数轴上有N个城市和M个信号塔,给你这N个城市以及M个塔在数轴上的位置,求M个塔可以覆盖N个城市的最小半径r。

思路:

  刚开始想的是,对半径进行二分,但是考虑到每次对半径进行二分后,要判断这M个塔是否已经可以覆盖N个城市,判断这里找不到时间复杂度比较好的写法。后面想了想,对于每个城市,找到距离其最近的塔,计算出距离,在这N个距离中取最大的距离,就是最后要找的最小半径r了,这里同样利用二分来找距离城市最进的塔,二分的时候找到距离城市右边最近的塔,然后和城市左边第一个塔和城市的距离做判断,取较小的,就是距离城市最近的塔到城市的距离了。

代码:

 1 #include <iostream>
 2 #include <cmath>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cstdlib>
 6 #include <stack>
 7 #include <queue>
 8 #include <vector>
 9 #include <algorithm>
10 #include <string>
11 #define mearv(a, b) memset(a, b, sizeof(a))
12 #define mestrc(a, b, c) memset(&(a), b, sizeof(c))
13 
14 typedef long long LL;
15 using namespace std;
16 const int MAXN = 100000;
17 const LL INF = 1e15;
18 
19 int main() {
20     LL a[MAXN + 3] = {0}, b[MAXN + 3] = {0};
21     LL n, m;
22     scanf("%I64d%I64d", &n, &m);
23     for(int i = 0; i < n; i++) scanf("%I64d", &a[i]);
24     for(int i = 0; i < m; i++) scanf("%I64d", &b[i]);
25     b[m] = INF;
26     LL ans = -1;
27     for(int i = 0; i < n; i++){
28         int lo = 0, hi = m;
29         while(lo <= hi){//对塔进行二分,找到城市右边距离城市最进的塔。
30             int mid = (lo + hi) >> 1;
31             if(a[i] <= b[mid]) hi = mid - 1;
32             else lo = mid + 1;
33         }
34         int minn = lo;
35         if(lo > 0 && (b[lo] - a[i] > a[i] - b[lo - 1]) ) minn = lo - 1;//和城市左边第一个塔进行比较
36         ans = max(ans, abs(b[minn] - a[i]));//每次结果取最大值
37     }
38     printf("%I64d
", ans);
39     return 0;
40 }
原文地址:https://www.cnblogs.com/Ash-ly/p/5725245.html