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

A - The King's Race

题意:初始有一个 n*n 棋盘有一黑一白两个旗子,白的在(1, 1)上,黑的在(n, n)上。每次可以将旗子移动到周围一圈这八个位置,给你三个数n, a, b(1 <= a, b <= n <= 10 ^ 18),让你求那个旗子可以先到达(a, b)。注:先移动的是白棋。

只要求出黑棋到(a, b)和白棋到(a, b)的步数,如果白棋小于等于(因为白棋动下)黑棋的,那么就是白棋,否则就是黑棋。

步数:就是ans1=fabs(a-1)+abs(b-1);    ans2=fabs(n-a)+abs(n-b);

代码如下

#include<bits/stdc++.h>
using namespace std;
int main()
{
    long long   n,a,b;
    while(~scanf("%lld",&n))
    {
        scanf("%lld %lld",&a,&b);
        long long  an1=fabs(a-1)+abs(b-1);
        long long  an2=fabs(n-a)+abs(n-b);
        if(an1<=an2) printf("White\n");
        else printf("Black\n");
    }
}

B - Taxi drivers and Lyft

题意:一条路上有n个乘客和m个出租车司机,给你他们的坐标(增序且保证没有坐标相同),每个乘客会向最近的一个司机发送订单,假如有两个最近的司机,发给坐标小的。求每个司机会收到多少个订单。

简单模拟 特别处理一下 开头段的乘客全部让第一个司机搭

代码:

#include <bits/stdc++.h>
using namespace std;
#define MAXN 200005
int n,m;
int x[MAXN], t[MAXN], tax[MAXN], ans[MAXN];//序号坐标 是否是司机 第几个司机的序号 答案
signed main()
{
  cin >> n >> m;
  for (int i = 1; i <= n + m; i++)
    cin >> x[i];//各自坐标
  int indice = 1;
  for (int i = 1; i <= n + m; i++)
  {
    cin >> t[i];//居民 or 司机
    if (t[i])//司机
    {
      tax[indice] = i;//第几个是司机
      indice++;//有几个司机
    }
  }
  int ind = 0;
  for (int i = 1; i <= n + m; i++)
  {
     // printf("%d\n",i);
    if (t[i]) ind++;//第几个司机
    else if (ind==0) //前面的乘客全部让第一个司机搭
               ans[1]++;
    else
    {
      if (abs(x[i] - x[tax[ind]]) <= abs(x[i] - x[tax[ind + 1]]))//比较最近的两个司机 哪个更近
        ans[ind]++;
      else ans[ind + 1]++;//右边更近
    }
  }
  for (int i = 1; i <= indice - 1; i++)
    cout << ans[i] << ' ';

}

题意:在一个(10 ^ 9) * (10 ^ 9)棋盘的(1, 1)有一个车,需要走到最上面一行。现在有n个竖行障碍和m个横行障碍,(两个竖行障碍不会在同一地方),(两个横行障碍不会有任何接触),现在问你最少去掉多少障碍使得车能到达。

因为横行障碍不会相交,且竖行障碍都是整行禁止通行的,那么只要横线左端x1[i]不是1那么这个障碍i就一定不用删去,障碍i要删去仅当横线右端x2[i] >= x[j]都被删除(j为余下的最左边的竖行障碍。注:以上的最好手动模拟。

因为竖行障碍是整行都禁止通行且起点再(1, 1),那么如果删掉第i竖行障碍,所有x[j] < x[i] 的障碍j都要删掉,不然障碍i删掉和不删掉一样。

我们只要将a[i]排个序,记录所有x1[i] = 1的障碍i的右端x2[i]并排序。然后枚举i表示1~i的竖行障碍被删除,然后可以求得当前情况下要删掉的横行障碍

代码如下

#include<bits/stdc++.h>
using namespace std;
const int N=100005;
const int M=1e9;
int a[N],b[N];//竖线 横线
int main()
{
  int n,m,x,x1,y;
  scanf("%d%d",&n,&m);
  int c=0;
  for(int i=1; i<=n; i++)
    scanf("%d",&a[i]);
  sort(a+1,a+1+n);
  a[n+1]=M;
  for(int i=1; i<=m; i++)
  {
    scanf("%d%d%d",&x,&x1,&y);
    if(x==1) b[++c]=x1;//记录1为起点的横的右端点
  }//只有从1为起点的横 才有可能是阻碍
  sort(b+1,b+1+c);
  int ans=M;
  for(int i=1; i<=n+1; i++)//第几条竖线
  {
    int id=lower_bound(b+1,b+1+c,a[i])-b;//竖线与各个右端点比较排第几
    ans=min(ans,i+c-id);//从原点开始走x轴 从竖线左边直上 or 通过竖线右边直上
  }
  printf("%d\n",ans);
  return 0;
}
/*
2 3
6 8
1 5 6
1 9 4
2 4 2

2 3
4
6
1 4 3
1 5 2
1 6 5
*/

猜你喜欢

转载自blog.csdn.net/qq_41668093/article/details/83902624
今日推荐