• 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
  • 相关阅读:
    ArcEngine 图层渲染(转)
    新年快乐!
    js限制输入(转载)
    ArcEngine中使用上下左右键移动地图
    ArcEngine 渲染的使用
    Geometry 对象浅析
    AE数据加载
    基于arcgis server地图页面设计备忘
    AO中的一些基础类和接口
    ArcGIS Server 9.2数据加载
  • 原文地址:https://www.cnblogs.com/Dup4/p/10353502.html
Copyright © 2020-2023  润新知