zoukankan      html  css  js  c++  java
  • Lyft Level 5 Challenge 2018

    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], " 
    "[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
    ", 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
    ", st);
    72         fflush(stdout);
    73         st = -1;
    74         scanf("%d", &st); 
    75         if (visa[st])
    76         {
    77             printf("C %d
    ", st);
    78             fflush(stdout);
    79             continue;
    80         }
    81         BFS(st);
    82         //st = dfs(st, st);
    83         int ed;
    84         printf("A %d
    ", st);
    85         fflush(stdout);
    86         scanf("%d", &ed);
    87         if (visa[st] && visb[ed])
    88             printf("C %d
    ", 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
    ", 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

    F. Deduction Queries

    Upsolved.

    题意:

    两种操作

    $1;l;r;x 告知你[l, r]的异或和$

    $2;l;r 询问[l,r]的异或和,如果不知道就输出-1$

    思路:

    我们考虑异或的性质,就是异或两次就相当于删除

    对于每次给出的$l, r我们可以把l, r并在一起$

    $这样对于每个连通块中的节点,我们维护的是当前点到根的异或和$

    $这样连通块中任意两点都可以询问,答案就是两个到根的异或和再异或一下$

    $我们再考虑合并$

    $我们令a, b为给出的异或和, fa[a], fa[b]为其所在连通块的根$

    $我们发现这两个连通块有这样一条路径$

    $fa[a] -> a -> b -> fa[b]$

    $我们期望将fa[a] -> fa[b] 连一条边$

    $根据前面定义的性质 fa[a]要维护的权值就是[fa[a], fa[b]]的异或和$ 

    $那么这个权值就是 [fa[a], a] oplus [a, b] oplus [b, fa[b]]$

    为了方便操作,我们将右界$+1$

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 200010
     5 int q, t, l, r, x, last;
     6 map <int, int> fa, Xor, Rank;
     7 
     8 int find(int x)
     9 {
    10     if (fa[x] == x) return x;
    11     int root = find(fa[x]);
    12     Xor[x] ^= Xor[fa[x]];
    13     return fa[x] = root;
    14 }
    15 
    16 int main()
    17 {
    18     while (scanf("%d", &q) != EOF)
    19     {
    20         fa.clear(); Xor.clear(); Rank.clear(); last = 0;
    21         while (q--)
    22         {
    23             scanf("%d%d%d", &t, &l, &r);
    24             if (t == 1)
    25             {
    26                 scanf("%d", &x);
    27                 l ^= last;
    28                 r ^= last;
    29                 x ^= last;
    30                 if (l > r) swap(l, r);
    31                 ++r;
    32                 if (fa.find(l) == fa.end()) fa[l] = l, Xor[l] = 0;
    33                 if (fa.find(r) == fa.end()) fa[r] = r, Xor[r] = 0;
    34                 int fl = find(l), fr = find(r);
    35                 if (fl != fr)
    36                 {
    37                     if (Rank[fr] <= Rank[fl])
    38                     {
    39                         fa[fr] = fl;
    40                         Xor[fr] = Xor[l] ^ Xor[r] ^ x;    
    41                         if (Rank[fl] == Rank[fr]) ++Rank[fl];
    42                     }
    43                     else
    44                     {
    45                         fa[fl] = fr;
    46                         Xor[fl] = Xor[l] ^ Xor[r] ^ x;
    47                     }
    48                 }
    49             }
    50             else
    51             {
    52                 l ^= last;
    53                 r ^= last;
    54                 if (l > r) swap(l, r); ++r;
    55                 if (fa.find(l) == fa.end() || fa.find(r) == fa.end())
    56                 {
    57                     last = 1;
    58                     puts("-1");
    59                     continue;
    60                 }
    61                 int fl = find(l), fr = find(r);
    62                 if (fl != fr)
    63                 {
    64                     last = 1;
    65                     puts("-1");
    66                 }
    67                 else
    68                 {
    69                     last = Xor[l] ^ Xor[r];
    70                     printf("%d
    ", last);
    71                 }
    72             }
    73         }
    74     }
    75     return 0;
    76 }
    View Code
  • 相关阅读:
    如何使用SAP Intelligent Robotic Process Automation自动操作Excel
    OpenSAML 使用引导 IV: 安全特性
    Spring Cloud Zuul 网关使用与 OAuth2.0 认证授权服务
    微服务架构集大成者—Spring Cloud (转载)
    Spring Cloud Eureka 服务注册列表显示 IP 配置问题
    使用 Notification API 开启浏览器桌面提醒
    SignalR 中使用 MessagePack 序列化提高 WebSocket 通信性能
    配置 Nginx 的目录浏览功能
    关于 Nginx 配置 WebSocket 400 问题
    Migrate from ASP.NET Core 2.0 to 2.1
  • 原文地址:https://www.cnblogs.com/Dup4/p/10353502.html
Copyright © 2011-2022 走看看