[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 }
时间: 2024-10-19 09:39:38

[UVa 1335]Beijing Guards的相关文章

uva 1335 Beijing Guards(二分)

uva 1335 Beijing Guards Beijing was once surrounded by four rings of city walls: the Forbidden City Wall, the Imperial City Wall, the Inner City Wall, and finally the Outer City Wall. Most of these walls were demolished in the 50s and 60s to make way

【二分答案+贪心】UVa 1335 - Beijing Guards

Beijing was once surrounded by four rings of city walls: the Forbidden City Wall, the Imperial City Wall, the Inner City Wall, and finally the Outer City Wall. Most of these walls were demolished in the 50s and 60s to make way for roads. The walls we

Uva 长城守卫——1335 - Beijing Guards

二分查找+一定的技巧 1 #include<iostream> 2 using namespace std; 3 4 const int maxn=100000+10; 5 int n,r[maxn],Left[maxn],Right[maxn];//因为不用计算方案,所以可以按[1-r[i]]和[r[i]+1~p]中各拿几个分,当时没想到这个用set类写了个超耗时间的~~~~(>_<)~~~~ 6 7 bool ok(int p) 8 { 9 int x=r[1],y=p-r[1

Live Archive 3177 3177 - Beijing Guards 【枚举】

3177 - Beijing Guards Time limit: 3.000 seconds Beijing was once surrounded by four rings of city walls: the Forbidden City Wall, the Imperial City Wall, the Inner City Wall, and finally the Outer City Wall. Most of these walls were demolished in the

UVALIVE 3177 Beijing Guards

Description Beijing was once surrounded by four rings of city walls: the Forbidden City Wall, the Imperial City Wall, the Inner City Wall, and finally the Outer City Wall. Most of these walls were demolished in the 50s and 60s to make way for roads.

AYITACM2016省赛第三周M - Beijing Guards(贪心+二分)

Beijing was once surrounded by four rings of city walls: the Forbidden City Wall, the Imperial City Wall, the Inner City Wall, and ?nally the Outer City Wall. Most of these walls were demolished in the 50s and 60s to make way for roads. The walls wer

LA 3177 Beijing Guards(长城守卫)

贪心找最优策略.大白上有详解. 不过这里有几个值得思考的地方. 还有几个地方想不明白,脑子不够用了,先记着,改天再做一遍 #include <cstdio> #include <algorithm> using namespace std; const int maxn = 100005; int n,a[maxn],left[maxn],right[maxn]; bool ok(int p) { int x = a[1],y = p-a[1]; left[1] = a[1];ri

hbx的毒瘤贪心系列题解

毒瘤hbx的贪心专题系列题解 A Maximal gcd 题意:现在给定一个正整数 n.你需要找到 k 个严格递增的正整数a1,?a2,?...,?ak,满足他们的和等于 n 并且他们的最大公因数尽量大.如果不可能请输出 -1.\(1\leq n,k \leq 10^{10}\) 题解:把 n 的所有因子找出来后,求最大因子 x 满足\(x* \frac {k* (k+1)}{2}\leq n\)即可.序列就是\(1* x,2* x,...,(k-1)* x,n-x* \frac{k* (k-1

UVA 11080 - Place the Guards(二分图判定)

UVA 11080 - Place the Guards 题目链接 题意:一些城市.之间有道路相连,如今要安放警卫,警卫能看守到当前点周围的边,一条边仅仅能有一个警卫看守,问是否有方案,假设有最少放几个警卫 思路:二分图判定,判定过程记录下白点和黑点个数,小的就是要安放的个数,注意假设是0,那么应该是加1 代码: #include <cstdio> #include <cstring> #include <vector> using namespace std; con