题意
小罐喜欢查水表,这一天他来到了一条有 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;
}
总结
以后还是要手造样例对拍。