思路:
括号匹配好题
1.能碰撞的两个点坐标的奇偶性一定相同
2.一般的,当所有的点不需要经过撞墙反弹后才能碰撞时,坐标奇偶性相同的点碰撞的过程就是一个括号匹配进栈出栈的过程,向右走的点进栈遇到向左走的点就出栈。
3.一轮括号匹配结束后剩下的点只要左括号变右括号、右括号变左括号然后继续匹配。处理一般情况的时候多余的右括号先不动,多余的左括号变成右括号。因为撞了一次墙,所以左括号变右括号时需要挪到最左边。
MyCode:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 3e5 + 7, maxm = 4e5 + 7; struct node{ int id,idx; char dis; bool operator<(const node& a)const{ return idx<a.idx; } }q[maxn]; int ans[maxn]; signed main() { ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); int _,n,m; cin>>_; vector<deque<pair<int,int>>>cur(2); while(_--) { cin>>n>>m; for(int i=1;i<=n;++i) { cin>>q[i].idx; q[i].id=i; ans[i]=-1; } for(int i=1;i<=n;++i) cin>>q[i].dis; sort(q+1,q+1+n); for(int i=1,id,idx;i<=n;++i) { idx=q[i].idx,id=q[i].id; if(q[i].dis=='R') cur[idx%2].emplace_back(make_pair(id,idx)); else { if(cur[idx%2].size()) { int y=cur[idx%2].back().first,idy=cur[idx%2].back().second; cur[idx%2].pop_back(); // cout<<idx<<' '<<idy<<' '<<abs(idx-idy)/2<<'\n'; ans[id]=ans[y]=abs(idx-idy)/2; } else cur[idx%2].emplace_front(make_pair(id,-idx)); } } for(int i=0;i<2;++i) { int x,y,xx,yy; while(cur[i].size()>=2) { x=cur[i].back().first,xx=cur[i].back().second; cur[i].pop_back(); y=cur[i].back().first,yy=cur[i].back().second; cur[i].pop_back(); ans[x]=ans[y]=m-xx+(xx-yy)/2; } cur[i].clear(); } for(int i=1;i<=n;++i) cout<<ans[i]<<' '; cout<<'\n'; } return 0; }