[UVa 1335]Beijing Guards

Posted NaVi_Awson

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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\\n", 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\\n", 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\\n", ans);
64     }
65 }
66 
67 int main() {
68     while ((~scanf("%d", &n)) && n)
69         work();
70     return 0;
71 }

 

以上是关于[UVa 1335]Beijing Guards的主要内容,如果未能解决你的问题,请参考以下文章

[UVa 1335]Beijing Guards

Uva 长城守卫——1335 - Beijing Guards

UVALive 3177 Beijing Guards

UVA11080 - Place the Guards (二分图染色)

使用 Guards (Roles, JWT) 获取用户数据

[CareerCup] Guards in a museum 博物馆的警卫