真爱粉Tk(三)
题目链接:https://ac.nowcoder.com/acm/contest/107500/D
题意:
给定一个数组,需要划分成k个区间。
并且这些区间“25”子序列(数组的数字拼接成字符串)的最大出现次数要尽可能小
求“25”子序列最大出现次数最小值
思路:
经典二分答案,关键在于check怎么写
而check函数的写法在于如何统计25子串的出现次数
一种方法是对于二分出来的mid,如果划分出来的区间可以小于等于k,那么就满足条件(划分越多区间“25”子序列出现最大次数越小)
遍历数组统计cnt2,cnt25,如果遇到2那么cnt2++,如果遇到5那么cnt25++
当cnt25超过了给定的mid,说明该位置上的元素不能再划分到该区间了.需要另起一段
统计划分区间次数即可
bool check(int mid){
int countt=1;
int cnt2=0,cnt25=0;
for(int i=1;i<=n;){
string s;s=to_string(a[i]);
for(int j=0;j<s.size();j++){
if(s[j]=='2')cnt2++;
else if(s[j]=='5'){
cnt25+=cnt2;
if(cnt25>mid){
// countt++;
// cnt25=0;cnt2=0;break;
break;
}
}
}
if(cnt25>mid){
countt++;
cnt2=cnt25=0;
}else{
i++;
}
}
// debug(mid);
// debug(countt);
return countt<=k;
}
void solve(){
cin>>n>>k;
rep(i,1,n){
cin>>a[i];
}
int l=0,r=1e18;
int res;
while(l<=r){
int mid=l+r>>1;
if(check(mid)){
res=mid;
r=mid-1;
}else{
l=mid+1;
}
}
cout<<res<<endl;
}`