• 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 }
  • 相关阅读:
    C语言之分支语句
    C语言之运算符与表达式
    C语言之数据类型④——中文字符
    独特的对象引用:this
    理解赋值“=”的含义
    编写类的 “模板”
    类的定义
    Java语言规范
    第一周总结
    定义常量
  • 原文地址:https://www.cnblogs.com/Ash-ly/p/5725245.html
Copyright © 2020-2023  润新知