2022-04-05每日刷题打卡

2022-04-05每日刷题打卡

代码源——每日一题

碰撞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×105,0≤Xi≤109,0≤Yi≤10^9。

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

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

#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;
}

力扣——每日一题

762. 二进制表示中质数个计算置位

给你两个整数 left 和 right ,在闭区间 [left, right] 范围内,统计并返回 计算置位位数为质数 的整数个数。

计算置位位数 就是二进制表示中 1 的个数。

例如, 21 的二进制表示 10101 有 3 个计算置位。

示例 1:

输入:left = 6, right = 10
输出:4
解释:
6 -> 110 (2 个计算置位,2 是质数)
7 -> 111 (3 个计算置位,3 是质数)
9 -> 1001 (2 个计算置位,2 是质数)
10-> 1010 (2 个计算置位,2 是质数)
共计 4 个计算置位为质数的数字。

提示:

  • 1 <= left <= right <= 106
  • 0 <= right - left <= 104

位运算统计left到right中每一个数的二进制1的个数,再判断这个个数是不是质数。

class Solution {
public:
    int countPrimeSetBits(int left, int right) {
        int res=0;
        for(int i=left;i<=right;i++)
        {
            int ans=0;
            for(int j=0;j<=20;j++)
            {
                if(((i>>j)&1)==1)ans++;
            }
            bool flag=true;
            for(int i=2;i<=ans/i;i++)
            {
                if(ans%i==0)
                {
                    flag=false;
                    break;
                }
            }
            if(flag&&ans!=1)res++;
        }
        return res;
    }
};
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值