代码源:705、碰撞2

165 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情logo.png

题目描述

这是4月5日代码源div2的每日一题。

碰撞2 - 题目 - Daimayuan Online Judge

在 xy 坐标系中有 N 个人,第 i 个人的位置是 (Xi,Yi),并且每个人的位置都不同。

我们有一个由 LR 组成的长为 N 的字符串 S,Si= R 代表第 i 个人面向右,Si= L 代表第 i 个人面向左。

现在所有人开始朝着他们各自面向的方向走,即面向右 x 就增,面向左 x 就减。

例如,当 (X1,Y1)=(2,3),(X2,Y2)=(1,1),(X3,Y3)=(4,1),S= RRL 时,人们的移动如图。

f33104f8bc05a920f2b74ead8ad1e3d2.png

我们把两个人对向行走到一个位置称为一次碰撞。请问如果人们可以无限走下去,会有人产生碰撞吗?

输入格式

第一行一个整数 N;

接下来 N 行,每行两个整数 Xi 和 Yi,表示第 i 个人的位置;

最后一行是一个由 LR 组成的长为 N 的字符串 S。

输出格式

如果会有碰撞,输出 Yes,否则输出 No

样例输入 1

3
2 3
1 1
4 1
RRL

样例输出 1

Yes

数据规模

所有数据保证 2≤N≤2×10^5,0≤Xi≤10^9,0≤Yi≤10^9。

问题解析

只有所处一条横线上的人才有可能相撞(y轴相同)。我们把所有的人以y轴区分,用一个哈希表,以y为key来存。用一个set容器做val(普通数组也可以,但要自己排序,我比较懒就用个能自动排序的容器),set存储的是一个数对,first是x轴,second是他们的方向。

要相撞,除了是一条直线上,还需要方向相反。但是必须是排在前面的人往右走,排在后面的人往左走才可以。如果排在前面的人往左走,排在前面的人往后走,那么这俩个人只会离得越来越远,更别提相撞了。所以我们把人根据y轴区分后,还要把他们以x排序,x小的排在前面,然后我们遍历一下y相同的人,只要前面有一个是向右走,且后面有一个向左走的,就说明他们会相撞,直接输出yes后结束程序即可。如果遍历所有的y轴都没有相撞的,就输出NO。

AC代码

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>

#define endl '\n';
typedef long long ll;
typedef pair<int, char> PII;

inline int read() {
    int x = 0; char ch = getchar();
    while (ch < '0' || ch > '9') ch = getchar();
    while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    return x;
}

void write(int x) {
    if (x > 9) write(x / 10);
    putchar(x % 10 | '0');
}

bool operator<(PII a, PII b)
{
    return a.first < b.first;
}
int main()
{
    int n;
    n = read();
    unordered_map<int, set<PII>>mymap;
    vector<pair<int,int>>v(n);
    for (int i = 0; i < n; i++)
    {
        v[i].first = read(), v[i].second = read();
    }
    string str;
    cin >> str;
    for (int i = 0; i < n; i++)
    {
        mymap[v[i].second].insert({ v[i].first,str[i]});
    }
    bool flag = false;
    for (auto i : mymap)
    {
        bool st = false;
        for (auto j : i.second)
        {
            if (j.second == 'R')st = true;
            else if (st && j.second == 'L')
            {
                flag = true;
                break;
            }
        }
        if (flag)break;
    }
    if (flag)
    {
        cout << "Yes" << endl;
    }
    else cout << "No" << endl;
    return 0;
}