CF1324C Frog Jumps 题解

原题链接

简要题意:

现在河面上有 \(n+2\) 块石头,编号 \(0\)\(n+1\)\(1\)~\(n\) 块石头每块上有一个方向,如果是 \(L\),那么青蛙到这块石头上之后只能往左跳,如果是 \(R\) 只能往右,当然,第 \(0\) 块石头的方向是 \(R\).

现在青蛙要从 \(0\) 跳到 \(n+1\),请问他应该怎么跳才能让他跳跃过程中跳跃距离最长的最小呢?输出这个距离。

显然,我们考虑贪心。

C题一点也不难啊

你想,如果你既可以跳到 \(L\) 点,又可以跳到 \(R\) 点,那么你会选哪个呢?
当然是 \(R\) 点啦!

如何说明呢?(严谨点)

如果 \(L\)\(R\) 的左边,那跳到 \(L\) 之后,只能一直往左,直到跳到一个 \(R\) 为止(总不能跳回去)。那么,你在跳这若干个 \(L\) 的第一个 \(L\) 的时候,既然能跳到 \(L\),那你直接选那个 \(R\) 不就行了,还浪费这么多步。

如果 \(L\)\(R\) 的右边,那跳到 \(L\) 之后,你只能回到这个 \(R\) 点;否则你只能一直往后跳,直到另一个 \(R\);那么你跳过来的路径又被你从跳回去了,还得再跳回来,那有什么意思,还浪费这么多步。

所以,上述已经说明,我们不跳 \(L\),只跳 \(R\) 是最优的。(最少步数)

那么,最小的最长跳跃距离是多少呢?不就是相邻两个 \(R\) 的最大距离吗?

分析了这么多,终于找到了题目的本质,直接可以解决问题了!

时间复杂度: \(O(T \times n)\).

因为总长度不超过 \(10^5\),所以是 \(O(10^5)\).

空间复杂度: \(O(n)\).

实际得分:\(100pts\).

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;

const int N=2e5+1;

inline int read(){char ch=getchar();int f=1;while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
	int x=0;while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;}

int T,n;
char s[N];

int main(){
	T=read(); while(T--) {
		scanf("%s",s);
		n=strlen(s);
		int k=-1,maxi=0; //k是上一个 R 的位置。因为 s 数组从 0 开始,所以这里从 -1 开始
		for(int i=0;i<n;i++)
			if(s[i]=='R') {
				maxi=max(i-k,maxi); //与上一个 R 的位置的距离
				k=i; //更新 R 的位置
			} 
		printf("%d\n",max(maxi,n-k));	//最后一个 R 到终点的距离也算一个答案
	}
	return 0;
}

猜你喜欢

转载自www.cnblogs.com/bifanwen/p/12550138.html