2022-04-05每日刷题打卡
代码源——每日一题
碰撞2 - 题目 - Daimayuan Online Judge
在 xy 坐标系中有 N 个人,第 i 个人的位置是 (Xi,Yi),并且每个人的位置都不同。
我们有一个由 L
和 R
组成的长为 N 的字符串 S,Si= R
代表第 i 个人面向右,Si= L
代表第 i 个人面向左。
现在所有人开始朝着他们各自面向的方向走,即面向右 x 就增,面向左 x 就减。
例如,当 (X1,Y1)=(2,3),(X2,Y2)=(1,1),(X3,Y3)=(4,1),S= RRL
时,人们的移动如图。
我们把两个人对向行走到一个位置称为一次碰撞。请问如果人们可以无限走下去,会有人产生碰撞吗?
输入格式
第一行一个整数 N;
接下来 N 行,每行两个整数 Xi 和 Yi,表示第 i 个人的位置;
最后一行是一个由 L
和 R
组成的长为 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;
}
};