2016 计蒜之道 初赛 第一场 青云的服务器密钥

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

对于密钥 S1..SnS_1..S_nS​1​​..S​n​​,我们需要首先计算其对应的π\piπ 数组。对于任意的 i(2≤i≤n)i(2 \leq i \leq n)i(2≤i≤n),π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{L∣S​1​​...S​L​​=S​i−L+1​​...S​i​​,(0≤L<i)}。也就是最长的前缀等于后缀的长度。

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

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

输入格式

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

输出格式

一共输出 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

一开始一脸懵逼,其实是一道贪心题。。。分两种情况:(1)如果只有一种字母或者没有(假设有n个),则答案为n*(n-1)/2; (2)如果有多种字母,先任选一种的一个放在第一个,那么后面一位放的时候选择与第一个字母不同的就可以使这一点的π值为零,而与第一个字母相同的字母应该加到最后,这样可以保证答案尽量小。在这种贪心策略下,第一个放的就应该是数量最少的一种字母,可以使答案最小,为n-1。其实O(n)的复杂度就可以,懒得改了。。。代码:

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
bool cmp(const int a,const int b)
{
return a > b;
}
int a[30];
int main()
{
int t;
cin>>t;
while(t--)
{
for(int i = 0;i < 26; ++i) cin>>a[i];
sort(a,a + 26,cmp);
int p = 0,sum = 0;
for(int i = 0;i < 26; ++i) if(a[i]) p = a[i],++sum;
if(sum <= 1) cout<<p * (p - 1) / 2<<endl;
else cout<<p - 1<<endl;
}
return 0;
}

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值