CSP-J 2025 入门级模拟赛 Day6 复盘 B. 罐の水表

题意

小罐喜欢查水表,这一天他来到了一条有 N 个排成一列的水表的街道查水表。
经过鉴定,他发现有一些水表损坏了,1 表示损坏,0 表示完好。
小罐每次可以使一段长度为 L 的连续的水表全部完好如初( 覆盖的范围可以超出地图),当然 L 越大,小罐越急。
小罐希望最多使用 K 次修复操作就将所有损坏的水表全部修复完成,但是为了让自己不那么急。他想知道能够达到这个目的的 L 最小是多少。

赛时做法

手玩了一下样例,发现L=N/K,所以直接敲上去了。

#include<bits/stdc++.h>
#include<bits/extc++.h>
using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
int n,k,f,l;
char c;
int main(){
	freopen("tenshi.in","r",stdin);
	freopen("tenshi.out","w",stdout);
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	cin >> n >> k;
	for(int i=1;i<=n;i++){
		cin >> c;
		if(c=='1'){
			if(!f)f=i;
			l=i;
		}
	}
	cout << (l-f+1)/k;
}

其实明显不对,5pts。

赛后反思

l有单调性,考虑二分答案,判断是否达到k次。

#include<bits/stdc++.h>
#include<bits/extc++.h>
using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
#define int long long
const int N=5e5+5;
int n,k,ans,l,r,mid,a;
string s;
bool c(int l){
	int cnt=0;
	for(int i=0;i<n;i++)if(s[i]=='1')cnt++,i+=l-1;
	return cnt<=k;
}
int32_t main(){
	freopen("tenshi.in","r",stdin);
	freopen("tenshi.out","w",stdout);
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	cin >> n >> k >> s;
	l=0,r=n;
	while(l<=r){
		mid=(l+r)/2;
		if(c(mid))r=(a=mid)-1;
		else l=mid+1;
	}
	cout << a;
}

总结

以后还是要手造样例对拍。

posted @ 2025-10-14 22:00  NotMonika  阅读(9)  评论(0)    收藏  举报