原题链接
题意:
有n个机器人在OX轴上运动,运动范围为[0,m]。
第i个机器人开始位于xi的位置,然后以1单位距离每秒的速度向左或向右运动,当其运动到0点或m点时会调转方向。
如果任意时刻多于一个机器人在同一整数位置,它们将会爆炸,爆炸后不再存在于OX轴上。一开始所有机器人位置不同。
求出每个机器人爆炸的时间,如果永远不会爆炸,输出-1
。
思路:
机器人在什么时候会碰撞,也就是当俩俩面对面的时候才会碰撞(好吧是一句废话)
给的机器人不一定是按照顺序给的所以要进行排序
换个说法,如果不考虑边界的情况下,机器人会有几种情况,答案是三种:
相向而行,俩俩之间距离 -2
背道而驰,俩俩之间距离 +2
同向而行,永远都不会见面(就像俩个世界的人,永远不会相交(😢))
此时我们在加上边界,那么机器人不管怎么走都也只会这三种情况里面跳转,这个时候你在纸上画个线段就会发现,如果所在下标的奇偶性不同的话,那么这俩个机器人碰撞时间计算怎么算都要 +1,也就是会擦肩而过(因为按照题目的意思来说,只有同时停留在相同整数点上的机器人才会爆炸(所以出生的位置就有时候能决定俩个人能不能相遇(😢))所以得出结论:它们初始坐标差为偶,那么它们一定会碰撞,因为边界的存在。
这个时候我们把下标同为奇和偶分开来求。其实就相当于一个括号匹配的过程,只有“)(”这样的括号才会碰撞,因为机器人是会动的,所以怎么去找到“)(”这样状态的括号,就可以用栈去模拟,“R”都往栈里面塞,“L”出现之后,弹出栈尾,进行碰撞
当我们知道哪两个机器人将会碰撞时,就可以进行碰撞事件的计算,假设两机器人初始坐标为x1,x2(x1<x2)(这俩点之间的差为偶数,也就是下标奇偶性相同),那么碰撞时间为:
初始方向为R,L
: (x2 − x1) / 2
初始方向为L,R
: m − (x2 − x1) / 2
初始方向为L,L
: (x1 + x2) / 2
初始方向为R,R
: m-(x1 + x2)/ 2
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<stack>
#include<string>
#include<algorithm>
#include<unordered_map>
#include<map>
#include<cstring>
#include <unordered_set>
//#include<priority_queue>
#include<queue>
#include<set>
#include<stdlib.h>
#define dbug cout<<"hear!"<<endl;
#define rep(a,b,c) for(ll a=b;a<=c;a++)
#define per(a,b,c) for(ll a=b;a>=c;a--)
#define no cout<<"NO"<<endl;
#define yes cout<<"YES"<<endl;
#define endl "\n"
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
//priority_queue<int,vector<int>,greater<int> >q;
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> PII;
typedef pair<long double,long double> PDD;
ll INF = 0x3f3f3f3f;
//const ll LINF=LLONG_MAX;
ll gcdd(ll a, ll b)
{
while(b^=a^=b^=a%=b);
return a;
}
// ll lcmm(ll a,ll b)
// {
// ll ans;
// ans=a/gcdd(a,b)*b;
// return ans;
// }
//ll idx;
const ll N = 2e6+ 10;
const ll mod =998244353;
ll t,n,m,x,y,ca;
ll arr[N],brr[N],crr[N];
ll book[N];
// ll ne[N],e[N],w[N];
// ll h[N],idx;
// void add(ll a,ll b, ll c)
// {
// e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++ ;
// }
struct node
{
ll x, id;
ll flag;
}noda[N];
bool cmp(node a,node b)
{
return a.x<b.x;
}
void fatchuan()
{
// vector< pair<ll,char> >ve;
cin>>n>>m;
rep(i,1,n)
{
cin>>noda[i].x;
noda[i].id=i;
arr[i]=-1;
}
rep(i,1,n)
{
char p;
cin >> p;
if(p == 'R')noda[i].flag = 1;
else noda[i].flag = 0;
}
sort(noda + 1, noda + 1 + n, cmp);
stack<ll>st;
rep(i,1,n)
{
if(noda[i].x % 2 == 1)continue;
if(st.empty())
{
st.push(i);
continue;
}
if(noda[i].flag == 1)
{
st.push(i);
}else
{
ll he = st.top();
st.pop();
ll time = (noda[i].x - noda[he].x) / 2;
if(noda[he].flag == 1)
{
arr[noda[he].id] = time;
arr[noda[i].id] = time;
}else{
arr[noda[he].id] = time + noda[he].x;
arr[noda[i].id] = time + noda[he].x;
}
}
}
while (st.size() >= 2) {
ll i = st.top();
st.pop();
ll j = st.top();
st.pop();
if (noda[i].flag != noda[j].flag) {
arr[noda[i].id] = arr[noda[j].id] = m - (noda[i].x - noda[j].x) / 2;
}else
{
arr[noda[i].id] = arr[noda[j].id] = (m - (noda[i].x + noda[j].x) / 2);
}
}
while (!st.empty()) st.pop();
rep(i,1,n)
{
if(noda[i].x % 2 == 0)continue;
if(st.empty())
{
st.push(i);
continue;
}
if(noda[i].flag == 1)
{
st.push(i);
continue;
}else
{
ll he = st.top();
st.pop();
ll time = (noda[i].x - noda[he].x) / 2;
if(noda[he].flag == 1)
{
arr[noda[he].id] = time;
arr[noda[i].id] = time;
}else{
arr[noda[he].id] = time + noda[he].x;
arr[noda[i].id] = time + noda[he].x;
}
}
}
while (st.size() >= 2) {
ll i = st.top();
st.pop();
ll j = st.top();
st.pop();
if (noda[i].flag != noda[j].flag) {
arr[noda[i].id] = arr[noda[j].id] = m - (noda[i].x - noda[j].x) / 2;
}else
{
arr[noda[i].id] = arr[noda[j].id] = (m - (noda[i].x + noda[j].x) / 2);
}
}
rep(i,1,n)
{
cout<<arr[i]<<' ';
}
cout<<endl;
}
int main()
{
IOS;
t=1;
//scanf("%d",&t);
cin>>t;
ca=1;
while(t--)
{
fatchuan();
ca++;
}
return 0;
}