青云的服务器密钥

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_34263473/article/details/51598527


                                                   青云的服务器密钥                                                         

                                                                                              1000ms                                 131072K                                

青云给每台服务器设置了一个由小写字母a-z组成的密钥。密钥的易破解程度定义如下:

对于密钥 S1..SnS_1..S_nS1..Sn,我们需要首先计算其对应的 π\piπ 数组。对于任意的 i(2≤i≤n)i(2 \leq i \leq n)i(2in)πi=max{L∣S1...SL=Si−L+1...Si,(0≤L<i)}\pi_i=max\{L|S_1...S_L=S_{i-L+1}...S_i, (0 \leq L < i)\}πi=max{LS1...SL=SiL+1...Si,(0L<i)}。也就是最长的前缀等于后缀的长度。

则密钥的易破解程度为 ∑i=2nπi\sum_{i=2}^{n}\pi_ii=2nπi,值越小,易破解程度越高。

现在已知密钥的 S1...SnS_1...S_nS1...Sn 中每个小写字母的字符个数,小明想知道易破解程度最高是多少?


输入格式

第一行一个正整数 T(1≤T≤10)T (1 \leq T \leq 10)T(1T10) 表示数据的组数。每组数据一行,262626 个非负整数 cnti(0≤∑icnti≤50)cnt_i(0 \leq \sum_{i}cnt_i \leq 50)cnti(0icnti50),表示密钥中每个小写字母的个数。


输出格式

一共输出 TTT 行,每行一个整数,为每组输入对应的易破解程度最高的结果。


样例输入

1
2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

样例输出

1

提示信息

abba是一个符合输入的密钥,除了 π4=1\pi_4 = 1π4=1,其他都是 000,因此 ∑i=2nπi=1\sum_{i=2}^{n}\pi_i=1i=2nπi=1

题意:就是给定一个只含26个小写字母的序列,让你组合,使得它所有的πi值之和最小,其中πi的定义是在子序列1到i这段,在找到一个L的位置,使得以L为子序列的分界,从1正数开始L个与从i倒数L个的序列相同,L即为此时的πi值。

题目链接:青云的服务器密钥

解题思路:解题首先要看懂题目,刚开始连题目看了好久。分两种情况:

1.只有一种字母。

这时,当字母数cnt>=2,对应的π值应该为cnt-1,比如 “aaaaa",π1=0,π2=1(a,a),π3=2(aa,aa(中间重合了一个a)),π4=3(123,432(对应a的位置)),π2=4(aaaa,aaaa(表示的含义前面已经说了)),相加结果为10,

不难发现规律,就为一个以1为首项,cnt-1为尾项的等差数列和。

2.两种或者以上的字母。

想要让总和最小,那么肯定想办法让他子序列重合的部分越少,因为子序列比较的位置是从1开始(这点是固定的),那么我们就把某个字母安排在这,它同种类的其他字母安排到最后,那么前面不含这个字母的部分的π值都将为0,从开始出现这个字符,才有π值,且只能为1,因为后缀只能和1号位置的匹配,这样答案就应该是这个字母出现次数cnt-1。

代码:

//青云的服务器密钥
//链接:http://nanti.jisuanke.com/t/11162
#include
#include

using namespace std;
int a[30];
int main()
{
    int T,i,ans,cnt,mx;
    cin>>T;
    while(T--){
        mx=0x3f3f3f3f;
        for(i=cnt=0;i<26;i++){
            cin>>a[i];
            if(a[i]){
                cnt++;                              //记住单词的种类
                mx=min(mx,a[i]);                   //更新最小单词出现的次数
            }
        }
        if(cnt==0){
            ans=0;
        }
        else if(cnt==1){
            ans=mx*(mx-1)/2;
        }
        else ans=mx-1;
        cout<

                                        

阅读更多
换一批

没有更多推荐了,返回首页