题意
从0号点到n号点排列在直线上。
n条有向边连接着这些点。
L表示向左,R表示向右。
对于每一个点,求它起点最多可达多少个点。
思路
- 首先考虑LRLR相间的情况:
在这样的子段上,奇数点(从0开始算)可达子段所有点,偶数点所有点都不可达 - 然后考虑RRRR/LLLL的情况:
在这样的子段上,每个点都只能到达自己和旁边的一个点,共2个点
所有的段都是由这两种情况组成的 - 考虑接壤LLR的情况:
0L1R2R3 1 3 2 1
接壤情况不存在相互影响
综合来看,只需要考虑每个点左边是不是L 右边是不是R即可
如果左边是L,或右边是R,就看顺着方向,看交叉的路能走到多远
Solution
#include <bits/stdc++.h>
#define sc(x) scanf("%d", &(x))
#define pr(x) printf("%d\n", (x))
#define rep(i, l, r) for (int i = (l); i <= (r); ++i)
using namespace std;
typedef long long ll;
const int N = 1e5 + 7;
const int mod = 1e9 + 7;
int main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int T, n;
cin >> T;
string s;
while (T--) {
cin >> n >> s;
vector<int> L(n), R(n); // 左右延伸距离
L[0] = 1;
for (int i = 1; i < n; i++) {
if (s[i] == s[i - 1])
L[i] = 1;
else
L[i] = L[i - 1] + 1;
}
R[n - 1] = 1;
for (int i = n - 2; i >= 0; i--) {
if (s[i] == s[i + 1])
R[i] = 1;
else
R[i] = R[i + 1] + 1;
}
for (int i = 0; i <= n; i++) {
int ans = 1;
if (i) ans += s[i - 1] == 'L' ? L[i - 1] : 0;
if (i != n) ans += s[i] == 'R' ? R[i] : 0;
cout << ans << ' ';
}
cout << '\n';
}
return 0;
}
/*
0 1 2 3
l r l
r l r
*/ 
京公网安备 11010502036488号