1. 程式人生 > >[UVa 1335]Beijing Guards

[UVa 1335]Beijing Guards

個人 return pre alt map $1 span pan div

技術分享

題解

拿到題,沒什麽頭緒,我們模擬一下,很容易得出一個結論:

如果$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