1. 程式人生 > >Lyft Level 5 Challenge 2018 - Final Round (Open Div. 2)

Lyft Level 5 Challenge 2018 - Final Round (Open Div. 2)

選擇 visa n) isp 需要 display 現在 empty 矩形

A. The King‘s Race

簽.

技術分享圖片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define ll long long
 5 ll n, x, y;
 6 
 7 ll f(ll a, ll b)
 8 {
 9     return max(abs(a - x), abs(b - y));
10 }
11 
12 int main()
13 {
14     while (scanf("%lld%lld%lld", &n, &x, &y) != EOF)
15     {
16 puts(f(1, 1) <= f(n, n) ? "White" : "Black"); 17 } 18 return 0; 19 }
View Code

B. Taxi drivers and Lyft

簽.

技術分享圖片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 100010
 5 int n, m;
 6 struct node
 7 {
 8     int x, t, id, small, big, small_pos, big_pos; 
 9
}a[N << 1]; 10 int ans[N]; 11 12 int main() 13 { 14 while (scanf("%d%d", &n, &m) != EOF) 15 { 16 memset(ans, 0, sizeof ans); 17 for (int i = 1, x; i <= n + m; ++i) 18 { 19 scanf("%d", &x); 20 a[i].x = x; 21 } 22 for
(int i = 1, tmp = 0, t; i <= n + m; ++i) 23 { 24 scanf("%d", &t); 25 a[i].t = t; 26 if (t == 1) 27 a[i].id = ++tmp; 28 } 29 int Max = -((int)1e9 + 1), pos = -1; 30 for (int i = 1; i <= n + m; ++i) 31 { 32 if (a[i].t == 1) 33 { 34 Max = a[i].x; 35 pos = a[i].id; 36 } 37 else 38 { 39 a[i].small = Max; 40 a[i].small_pos = pos; 41 } 42 } 43 int Min = (int)2e9 + 1; pos = -1; 44 for (int i = n + m; i >= 1; --i) 45 { 46 if (a[i].t == 1) 47 { 48 Min = a[i].x; 49 pos = a[i].id; 50 } 51 else 52 { 53 a[i].big = Min; 54 a[i].big_pos = pos; 55 } 56 } 57 for (int i = 1; i <= n + m; ++i) if (a[i].t == 0) 58 { 59 int A = abs(a[i].x - a[i].small), B = abs(a[i].x - a[i].big); 60 if (A <= B) ++ans[a[i].small_pos]; 61 else ++ans[a[i].big_pos]; 62 } 63 for (int i = 1; i <= m; ++i) 64 printf("%d%c", ans[i], " \n"[i == m]); 65 } 66 return 0; 67 }
View Code

C. The Tower is Going Home

Solved.

題意:

要從$(1, 1) 走到(1e9, *)$

$有一些橫著和豎著的欄桿擋著,每次只能移動到曼哈頓距離為1的格子$

$求最小的需要去掉的欄桿的數量,使得可以到達目的地$

思路:

考慮橫著的欄桿,$如果左端點不是1,那麽該欄桿沒有用$

$那麽考慮從左到右掃一遍,豎著的欄桿按順序去掉後$

$右端點沒有超過該豎著欄桿的橫欄桿,該橫欄桿也沒有用$

更新答案即可

技術分享圖片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 100010
 5 int n, m, q;
 6 int a[N], b[N];
 7 
 8 
 9 int main()
10 {
11     while (scanf("%d%d", &n, &m) != EOF)
12     {
13         for (int i = 1; i <= n; ++i) scanf("%d", a + i);
14         sort(a + 1, a + 1 + n);
15         q = 0;
16         for (int i = 1, x1, x2, y; i <= m; ++i)
17         {
18             scanf("%d%d%d", &x1, &x2, &y);
19             if (x1 == 1) b[++q] = x2;
20         }
21         sort(b + 1, b + 1 + q);
22         int res = q;  
23         int pos = 0;
24         a[n + 1] = (int)1e9; 
25         for (int i = 0; i <= n; ++i)
26         {
27             while (pos < q && b[pos + 1] < a[i + 1]) ++pos;
28             res = min(res, i + q - pos);
29         }
30         printf("%d\n", res);
31     }
32     return 0;
33 }
View Code

D. Intersecting Subtrees

Upsolved.

題意:

有一棵樹,$A選了一棵子樹,B選了一棵子樹$

$但是B對樹的標號和A對樹的標號不同$

$現在告訴你以A標號的樹的形態$

$以及A, B各自選擇的子樹的標號$

$有5次詢問機會,每次可以詢問$

$A \; x\;\; 返回B對應的標號$

$B \; y \;\; 返回A對應的標號$

最後給出答案,$A, B選擇的子樹是否有交,有的話輸出其中一個交點,否則輸出-1$

思路:

隨便選一個$B中的點,得到A中的點,如果剛好是A子樹內的,直接輸出$

$否則以這個點去找一個最近的點,再詢問一次,如果是就輸出,否則就是-1$

$因為找到的是最近的屬於A選擇子樹內的點,說明這條路徑上沒有交,如果這個點不是交$

$那麽說明那個點那頭也不會有交$

$如果有交的話,這個點就會把B選擇的子樹分成兩部分,就不是連通的,和題意想違背$

技術分享圖片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 1010
 5 int t, n, k, st;
 6 int visa[N], visb[N];
 7 vector <int> G[N];
 8 
 9 int fa[N];
10 void BFS(int S) 
11 {
12     queue <int> q; q.push(S); fa[st] = S;
13     while (!q.empty())
14     {
15         int u = q.front(); q.pop();
16         if (visa[u]) 
17         {
18             st = u;
19             return; 
20         }
21         for (auto v : G[u]) if (v != fa[u])
22         {
23             fa[v] = u;
24             q.push(v);
25         }
26     }
27 }
28 
29 int dfs(int num,int fa){
30     if(visa[num]){
31         return num;
32     }
33     for (auto v : G[num]) if (v != fa) 
34     {
35         int temp=dfs(v,num);
36         if(temp!=-1){
37             return temp;
38         }
39     }
40     return -1;
41 }
42 
43 int main()
44 {
45     scanf("%d", &t);
46     while (t--)
47     {
48         scanf("%d", &n);
49         for (int i = 1; i <= n; ++i) G[i].clear();
50         memset(visa, 0, sizeof visa);
51         memset(visb, 0, sizeof visb);
52         for (int i = 1, u, v; i < n; ++i)
53         {
54             scanf("%d%d", &u, &v);
55             G[u].push_back(v);
56             G[v].push_back(u);
57         }
58         scanf("%d", &k);
59         for (int i = 1, x; i <= k; ++i)
60         {
61             scanf("%d", &x);
62             visa[x] = 1;
63         }    
64         scanf("%d", &k);
65         for (int i = 1, x; i <= k; ++i)
66         {
67             scanf("%d", &x);
68             visb[x] = 1;
69             st = x;
70         }
71         printf("B %d\n", st);
72         fflush(stdout);
73         st = -1;
74         scanf("%d", &st); 
75         if (visa[st])
76         {
77             printf("C %d\n", st);
78             fflush(stdout);
79             continue;
80         }
81         BFS(st);
82         //st = dfs(st, st);
83         int ed;
84         printf("A %d\n", st);
85         fflush(stdout);
86         scanf("%d", &ed);
87         if (visa[st] && visb[ed])
88             printf("C %d\n", st);
89         else 
90             puts("C -1");
91         fflush(stdout);
92     }
93     return 0;
94 }
View Code

E. Optimal Polygon Perimeter

Upsolved.

題意:

給出一個凸包,兩點之間的距離為曼哈頓距離

定義$f(x) 為選擇x個點構成一個凸包的最大周長$

輸出$f(3), f(4) \cdots f(n)$

思路:

對於$n >= 4的答案,就是選擇最大上界,最大下界,最大左界,最大右界,構成的矩形的周長$

$再考慮n == 3的時候$

$因為是一個三角形,那麽肯定是某兩個最構成的兩個點,再加上一個點,那個點枚舉求解即可$

技術分享圖片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 300010
 5 int n;
 6 int x[N], y[N];
 7 
 8 int main()
 9 {
10     while (scanf("%d", &n) != EOF)
11     {
12         int Max[2], Min[2];
13         Min[0] = Min[1] = (int)1e9;
14         Max[0] = Max[1] = -(int)1e9;
15         for (int i = 1; i <= n; ++i)
16         {
17             scanf("%d%d", x + i, y + i);
18             Max[0] = max(Max[0], x[i]);
19             Min[0] = min(Min[0], x[i]);
20             Max[1] = max(Max[1], y[i]);
21             Min[1] = min(Min[1], y[i]);
22         }
23         if (n == 3)
24             printf("%d\n", 2 * (Max[0] + Max[1] - Min[0] - Min[1]));
25         else
26         {
27             int res = 0;
28             for (int i = 1; i <= n; ++i)
29                 res = max(res, max(abs(x[i] - Max[0]), abs(x[i] - Min[0])) + max(abs(y[i] - Max[1]), abs(y[i] - Min[1])));
30             res *= 2;
31             printf("%d", res);    
32             for (int i = 4; i <= n; ++i) 
33                 printf(" %d", 2 * (Max[0] + Max[1] - Min[0] - Min[1]));
34             puts("");
35         }
36     }
37     return 0;
38 }
View Code

Lyft Level 5 Challenge 2018 - Final Round (Open Div. 2)