真爱粉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;
}`
posted @ 2025-04-21 18:12  Marinaco  阅读(12)  评论(0)    收藏  举报
//雪花飘落效果