Codeforces Round #650 (Div. 3) E. Necklace Assembly 思维 暴力+二分

Posted cimonhe

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #650 (Div. 3) E. Necklace Assembly 思维 暴力+二分相关的知识,希望对你有一定的参考价值。

E. Necklace Assembly

技术图片

 

题目大意:

  给定一个长度为n的字符串s,和一个数k,从这个字符串s中选择一些字符组成一个周期为k的因子的最大字符串,并输出这个最大字符串的字符数(1<=n,k<=2000),有t组测试数据并且这t组测试数据的n的总数和不超过2000 (1<=t<=100)。

思路:

  首先数据范围小 暴力+二分即可。

  将每个字母的个数统计出来,枚举每个k的因子,以这些因子作为周期T,二分查找满足周期为T的最大个数。 

 

 代码:

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
#define N 2010
#define M 26
int factor[N],tot;
vector <int> v;

bool check(int x,int y)//判断能否凑出x个周期为T个字母的数 并且周期 T能否大于y
{
    if (!x)
        return true;
    int ans=0;
    for (auto a:v) 
        ans+=a/x;
    return ans>=y;
}

void solve()
{
    
    int cntletter[M]={0}; 
    v.clear();
    int n,k;
    tot=0;
    string s;
    cin>>n>>k;
    cin>>s;
    for (int i=2;i<=k;i++)            //将k的因子放进factor数组中 
        if (k%i==0)
            factor[++tot]=i;
    for (int i=0;i<s.size();i++)    //统计各个字母出现的次数 
        cntletter[s[i]-a]++;
    for (int i=0;i<M;i++)             //将各个字母出现次数大于0的数量放进v中
        if (cntletter[i])
            v.push_back(cntletter[i]);
    sort(v.begin(),v.end());        //将v从小到大排序 
    int ans=v.back();
    for (int i=1;i<=tot;i++)        //以k的各个因子为周期遍历一遍         
    {
        int l=0,r=n,mid;
        int res=0;
        while (l<=r)                //二分查找出以该因子为周期最大的数目 
        {
            mid=(l+r)/2;
            if (check(mid,factor[i]))
            {
                res=mid;
                l=mid+1;
             } 
             else
                 r=mid-1;
        }
        ans=max(ans,res*factor[i]);
    }
    cout<<ans<<endl;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int t;
    cin>>t;
    while (t--)
        solve();
    return 0;
} 

赛后补题:

原作者:https://blog.csdn.net/qq_43627087/article/details/106807131

 

以上是关于Codeforces Round #650 (Div. 3) E. Necklace Assembly 思维 暴力+二分的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #650 (Div. 3) A. Short Substrings

Codeforces Round #650 (Div. 3) C. Social Distance

Codeforces Round #650 (Div. 3) C. Social Distance (前缀和)

Codeforces Round #436 E. Fire(背包dp+输出路径)

Codeforces Round #650 (Div. 3) E. Necklace Assembly (暴力)

Codeforces Round #650 (Div. 3) D : Task On The Board