题目
CF1525C :点这里
题目大意:给定n,m,其中n代表机器人,m代表边界,每个机器人有方向L,R,走到同一位置上面会爆炸,走到0或边界m上面,下一秒会改变方向返回,最后输出每个机器人爆炸的时间
算法思路
- 括号匹配思路,用堆栈来做,L相当于右括号,R相当于左括号,对撞相当于匹配
- 只有坐标的奇偶性相同,才有可能对撞,因为同向移动,距离改变0,异向移动,距离改变为-2或+2,奇偶性永远不会改变,所以只需要针对奇偶性,分开处理坐标为奇数,和坐标为偶数的即可
- 将坐标按照从小到大排序一遍,然后i从1到n开始处理,但是要记录原来的爆炸时间,所以每个结构体还得带上一个成员变量id
- 如果是R(左括号)则直接入栈,
- 如果是L(右括号),则查看栈中是否有东西
- 如果东西,则取出栈顶,对撞输出二者的答案,
ans[a[i].id]=ans[a[stk1[top1]].id]=(a[i].x-a[stk1[top1]].x)/2
,二者之间的距离除以二 - 如果没有东西,代表L(右括号)会变成R(左括号),此时分享改变后的x坐标相当于镜像,即
a[i].x=-a[i].x
- 栈中最后可能还有剩余东西,即全部都是R(左括号),这种情况,栈顶的元素又会反转成为L(右括号),栈中的top和top-1个元素会抵消,所以答案为
ans[a[stk1[top1]].id]=ans[a[stk1[top1-1]].id]=(2*(m-a[stk1[top1]].x)+a[stk1[top1]].x-a[stk1[top1-1]].x)/2
- 最后每个奇偶性的栈里面,最多只剩下一个机器人,那么这个机起人永远不会爆炸,这个时候我们就可以在初值的地方全部赋值为-1
代码实现
#include<bits/stdc++.h>
#include<unordered_map>
#include<unordered_set>
using namespace std;
#define el '\n'
#define cl putchar('\n')
#define pb push_back
#define eb emplace_back
#define fir first
#define sec second
typedef long long ll;
typedef pair<int,int> pii;
typedef vector<int> vci;
typedef map<int,int> mii;
typedef mii::iterator mii_it;
const int N=3e5+10,M=1e3+10;
struct node{
int x,id;
char b;
}a[N];
int ans[N],stk1[N],stk2[N],top1,top2;
int cmp(node x,node y){
return x.x<y.x;
}
int T,n,m;
int main() {
cin.tie(0);
cout.tie(0);
cin>>T;
while(T--) {
cin>>n>>m;
top1=top2=0;
memset(ans,-1,sizeof(ans));
for(int i=1; i<=n; i++) {
cin>>a[i].x;
a[i].id=i;
}
for(int i=1; i<=n; i++)cin>>a[i].b;
sort(a+1,a+n+1,cmp);
for(int i=1; i<=n; i++) {
// cout<<"#";
// for(int j=1;j<=top1;j++){
// cout<<stk1[j]<<' ';
// }
// cl;
// for(int j=1;j<=top2;j++){
// cout<<stk2[j]<<' ';
// }
// cl;
if(a[i].x%2==0) {
if(a[i].b=='L') {
if(top1>0) {
ans[a[i].id]=ans[a[stk1[top1]].id]=(a[i].x-a[stk1[top1]].x)/2;
top1--;
} else {
stk1[++top1]=i;
a[i].x=-a[i].x;
}
} else {
stk1[++top1]=i;
}
}
else {
if(a[i].b=='L') {
if(top2>0) {
ans[a[i].id]=ans[a[stk2[top2]].id]=(a[i].x-a[stk2[top2]].x)/2;
top2--;
} else {
stk2[++top2]=i;
a[i].x=-a[i].x;
}
} else {
stk2[++top2]=i;
}
}
}
while(top1>=2) {
ans[a[stk1[top1]].id]=ans[a[stk1[top1-1]].id]=(2*(m-a[stk1[top1]].x)+a[stk1[top1]].x-a[stk1[top1-1]].x)/2;
top1-=2;
}
while(top2>=2) {
ans[a[stk2[top2]].id]=ans[a[stk2[top2-1]].id]=(2*(m-a[stk2[top2]].x)+a[stk2[top2]].x-a[stk2[top2-1]].x)/2;
top2-=2;
}
for(int i=1;i<=n;i++){
cout<<ans[i]<<" ";
}
cl;
}
}