CF1476D题解

场上 \(O(n)\) 切掉的一道挺水的题。

首先向左走和向右走,一个很明显的结论是,如果向左走了一段距离又回到原点,那么方向是不会变的,所以只需要求出能够向左走的最远距离和向右走的最远距离,加起来即可。

看上去是 \(O(n^2)\) 的,实际上能够递推。

\(L[i]\)\(i\) 向左走的最远距离,\(R[i]\)\(i\) 向右走的最远距离。

\(i \leq n \And 2 \leq i\) 时,若从 \(i\) 开始能向左走 \(2\) 格(此时道路方向还原,那么相当于可以从 \(i-2\) 开始走),\(L[i] = L[i-2]+2\)\(R[i]\) 类似。

对于 \(0,1,n-1,n\) 可以特判。

code:

#include<algorithm>
#include<iostream>
#include<cstdio>
typedef long long ll;
const int M=3e5+5; 
int T,n,L[M],R[M];bool a[M];char s[M];
signed main(){
	register int i;
	scanf("%d",&T);
	while(T--){
		scanf(" %d%s",&n,s+1);
		for(i=1;i<=n;++i)a[i]=s[i]=='L';
		R[n]=0;R[n-1]=!a[n];
		L[0]=0;L[1]=a[1];
		for(i=n-2;i>=0;--i){
			if(!a[i+1]){
				if(a[i+2])R[i]=R[i+2]+2;
				else R[i]=1;
			}
			else R[i]=0;
		}
		for(i=2;i<=n;++i){
			if(a[i]){
				if(!a[i-1])L[i]=L[i-2]+2;
				else L[i]=1;
			}
			else L[i]=0;
		}
		for(i=0;i<=n;++i)printf("%d ",L[i]+R[i]+1);printf("\n");
	}
}
posted @ 2022-01-10 16:01  Prean  阅读(29)  评论(0编辑  收藏  举报
var canShowAdsense=function(){return !!0};