• [UVa 1335]Beijing Guards


    题解

    拿到题,没什么头绪,我们模拟一下,很容易得出一个结论:

    如果$n$为偶数,那么答案就是$max(r[i]+r[i+1])$。具体方案就是,如果$i$为奇数,那么取$[1,r[i]]$;若$i$为偶数,则取$[ans-r[i]+1,ans]$。

    同样我们此时的$ans$是答案的下界。

    可当$n$为奇数时,我们这样贪心策略出现问题就是由于$1$和$n$都是奇数,会取$[1,r[1]]$,$[1,r[n]]$显然会重复,那么奇数我们就不能这样做了。

    我们由$n$为偶数的思想,我们还是让$1$号取$[1,r[1]]$,那么就要让$n$尽量往“后”取,这样$n-1$就要尽量往“前”取……

    因此我们得出“除$1$以外奇数往后取,偶数往前取”,那么我们只需要通过假定的$ans$值,做一遍模拟即可。

    对于如何选取$ans$,我们可以去二分。

    另外一个方面,我们发现我们不需要知道我们到底是取了哪些值,我们最后只要知道是不是第$n$个人取了$[1,r[1]]$的数。那么我们把所有的数分为$[1,r[1]]$和$[r[1],ans]$两个区间,我们在区间内讨论即可。

    另外:注意$n == 1$的时候的特判,因为这个$wa$了很多次。

     1 //It is made by Awson on 2017.9.18
     2 #include <map>
     3 #include <set>
     4 #include <cmath>
     5 #include <ctime>
     6 #include <queue>
     7 #include <stack>
     8 #include <cstdio>
     9 #include <string>
    10 #include <vector>
    11 #include <cstdlib>
    12 #include <cstring>
    13 #include <iostream>
    14 #include <algorithm>
    15 #define LL long long
    16 #define Max(a, b) ((a) > (b) ? (a) : (b))
    17 #define Min(a, b) ((a) < (b) ? (a) : (b))
    18 #define Abs(a) ((a) < 0 ? (-(a)) : (a))
    19 using namespace std;
    20 const int N = 100000;
    21 
    22 int n, r[N+5];
    23 
    24 bool judge(int p) {
    25     int Left[N+5] = {0}, Right[N+5] = {0};
    26     int x = r[1], y = p-r[1];
    27     Left[1] = x;
    28     for (int i = 2; i <= n; i++) {
    29         if (i%2) {
    30             Right[i] = Min(y-Right[i-1], r[i]);
    31             Left[i] = r[i]-Right[i];
    32         }
    33         else {
    34             Left[i] = Min(x-Left[i-1], r[i]);
    35             Right[i] = r[i]-Left[i];
    36         }
    37     }
    38     return Left[n] == 0;
    39 }
    40 void work() {
    41     int L = 0, R = 0;
    42     for (int i = 1; i <= n; i++)
    43         scanf("%d", &r[i]);
    44     if (n == 1) {
    45         printf("%d
    ", r[1]);
    46         return;
    47     }
    48     r[n+1] = r[1];
    49     r[n+2] = r[2];
    50     for (int i = 1; i <= n; i++) {
    51         L = Max(L, r[i]+r[i+1]);
    52         R = Max(R, r[i]+r[i+1]+r[i+2]); 
    53     }
    54     if (!(n%2))
    55         printf("%d
    ", L);
    56     else {
    57         int ans = R;
    58         while (L <= R) {
    59             int mid = (L+R) >> 1;
    60             if (judge(mid)) R = mid-1, ans = mid;
    61             else L = mid+1;
    62         }
    63         printf("%d
    ", ans);
    64     }
    65 }
    66 
    67 int main() {
    68     while ((~scanf("%d", &n)) && n)
    69         work();
    70     return 0;
    71 }
  • 相关阅读:
    前端模块化开发的价值
    Promise对象
    avalon define新老风格对比
    jQuery知识点1
    SASS
    HTML5
    JSON
    css垂直居中
    maven nexus 部署
    Linux 平台下 lzo和hadoop-lzo安装与集成
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/7544892.html
Copyright © 2020-2023  润新知