蓝桥杯之每日一题

问题描述
有N盏灯排成一列,其中有些灯开着,有些灯关着。小可可希望灯是错落有致的,他定义一列灯的状态的不优美度为这些灯中最长的连续的开着或关着的灯的个数。小可可最多可以按开关k次,每次操作可以使该盏灯的状态取反:原来开着的就关着,反之开着。现在给出这些灯的状态,求操作后最小的不优美度。
—————————————————————————————————————————————
输入格式
第一行两个整数n,k

第二行是一个长度为n的字符串,其中有两种字符:N和F。其中N表示该灯开着,F表示该灯关着

输出格式
最小的不优美度

样例 #1
样例输入 #1

8 1
NNNFFNNN

样例输出 #1

3

—————————————————————————————————————————————
提示
30%的数据:1 ≤ K ≤ N ≤ 20;

50%的数据:1 ≤ K ≤ N ≤ 300;

另有15%的数据:1 ≤ N ≤ 100000,字符串为全N或全F;

100%的数据:1 ≤ K ≤ N ≤ 100000。
—————–———————————————————————————————————————
解题思路
首先,求最小的最大值,且满足单调性,所以可以使用二分。
需要注意的是:
1.二分可以求出最小的不优美度,但是最小值为1,需要进行特判
2.二分得出的是一个可能的不优美度,[left, right]是最小不优美度可能的范围,其中初始left=1,right=n/k+1(尝试理解一下,不理解的话right=n也可)
在本题中,最小不优美度为1,需要进行特判:
比如FNNNFFNN,若最多可以按4次开关,求最小不优美度。
当不优美度为1时,有且仅有两种情况:
FNFNFNFN(需要按3次开关) 或
NFNFNFNF(需要按5次开关)
容易得出,想要一排灯不优美度为1仅有两种情况,且变成这两种情况所需按开关次数之和刚好为灯的数量
那么只要特别判断这两种情况即可
—————————————————————————————————————————————
解题代码

#include<iostream>
using namespace std;

int n, k;
string s;

int main()
{
	cin >> n >> k >> s;
	char c[2] = {'F', 'N'};//标记
	int p = 0;
	for(int i = 0; i < n; i++)//进行特判
		if(s[i] == c[i%2])
			p++;
	if(p <= k || n-p <= k){
		cout << 1 << endl;
		return 0;
	}
	
	int l = 2, r = n/k+1, mid;
	int cnt = 0;
	while(l <= r){
		mid = (l+r)/2;//一个可能的不优美度
		cnt = 0;
		for(int i = 0, j = 0, ans = 0; i < n; i++){
			if(s[i] == s[j])
				ans++;
			else
				j = i, ans = 1;
			if(mid < ans)
				j = i+1, ans = 0, cnt++;
		}
		//i表示连续的灯的最右端,j表示连续的灯的最左端,ans表示连续的灯的长度,cnt表示最少需要按多少次灯
		if(cnt <= k){
			r = mid - 1;
		}
		else{
			l = mid + 1;
		}
	}
	
	cout << l << endl;
	return 0;
}       
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数据分析不是个事儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值