您的位置:首页 > 其它

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

2017-05-20 18:40 162 查看
青云给每台服务器设置了一个由小写字母
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: