- 题解
孩子们的移动
- @ 2026-8-29 21:31:49
我们很容易发现,最终孩子一定会在一个RL的地方左右摇摆。
由此,S段自然会分成RRR..RL..LLL如此形式的子串,并且容易发现,这种子串互不相通,即孩子只会在一个子串内移动,绝对不会去到另一个子串里。
同时,我们又可以发现,当一边从交界处开始,第奇数个位置一定会停在交界处。如RRRL,从最右边的R(即交界处)开始数,第奇数个R最终还是会停止最右边的R上(即交界处),因为 是个偶数。
如此,我们就很容易发现,当L和R的数量和为偶数之时,交界处的RL孩子数量相等!根据如上。
但是如果不是偶数呢?我们依旧可以先看作是偶数的情况,如此就会发现多出了一个字符。同样,根据上面的结论,如果这个字符是第奇数位,则最终会落在自己这边,所以自己这边的边界再补(加)上个一就行了,同理可得,如果不是第奇数位,则在对方的边界再补(加)上个一就行了。
代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
int T = 1;
const int N = 2e5 + 1;
string s;
int arr[N];
void Solve() {
cin >> s;
int r = 0, l = 0;//l、r是L、R在子串里的数量
int idxl, idxr;//交界处下标
for (int i = 0; i < s.size(); i++) {
//由此R->L是标记交界
if (s[i] == 'R') {
r++;
if (s[i + 1] == 'L') {
idxr = i;
idxl = i + 1;
}
} else {//L->R(结束)是计算答案
l++;
if (i == s.size() - 1 || s[i + 1] == 'R') {
arr[idxl] = arr[idxr] = (l + r) / 2;
if ((l + r) & 1) {//奇数
if (l > r) {
if (l & 1) {
arr[idxl]++;
} else {
arr[idxr]++;
}
} else {
if (r & 1) {
arr[idxr]++;
} else {
arr[idxl]++;
}
}
}
l = r = 0;
}
}
}
for (int i = 0; i < s.size(); i++) {
cout << arr[i] << " ";
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
while (T--) {
Solve();
}
return 0;
}
0 条评论
目前还没有评论...