青云的服务器密钥            

  •                                                                                               1000ms                                 131072K                                
    青云给每台服务器设置了一个由小写字母a-z组成的密钥。密钥的易破解程度定义如下:
    对于密钥 青云容器中拷贝文件到宿主机 青云传仓库密码_2016计蒜之道,我们需要首先计算其对应的 青云容器中拷贝文件到宿主机 青云传仓库密码_水题_02 数组。对于任意的 青云容器中拷贝文件到宿主机 青云传仓库密码_子序列_03青云容器中拷贝文件到宿主机 青云传仓库密码_子序列_04。也就是最长的前缀等于后缀的长度。
    则密钥的易破解程度为 青云容器中拷贝文件到宿主机 青云传仓库密码_2016计蒜之道_05,值越小,易破解程度越高。
    现在已知密钥的 青云容器中拷贝文件到宿主机 青云传仓库密码_服务器_06 中每个小写字母的字符个数,小明想知道易破解程度最高是多少?


    输入格式
    第一行一个正整数 青云容器中拷贝文件到宿主机 青云传仓库密码_2016计蒜之道_07 表示数据的组数。每组数据一行,青云容器中拷贝文件到宿主机 青云传仓库密码_水题_08 个非负整数 青云容器中拷贝文件到宿主机 青云传仓库密码_水题_09,表示密钥中每个小写字母的个数。


    输出格式
    一共输出 青云容器中拷贝文件到宿主机 青云传仓库密码_水题_10 行,每行一个整数,为每组输入对应的易破解程度最高的结果。


样例输入

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是一个符合输入的密钥,除了 青云容器中拷贝文件到宿主机 青云传仓库密码_服务器_11,其他都是 青云容器中拷贝文件到宿主机 青云传仓库密码_水题_12,因此 青云容器中拷贝文件到宿主机 青云传仓库密码_水题_13

题意:就是给定一个只含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<
       
       
        
        <