#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N=100020;
const int Q=1e9+7;
int num[26][N];//字母在某位上出现的次数;
int n,L;
int power[N];//在某个位置上的权的大小
int sum[N];//权值总和;
int a[26];//26个字母;
bool ban[26];//是否出现了字母
char str[N];//每次出现的字符串;
bool cmp(int a,int b)
{
for(int i=L-1;i>=0;--i)
{
if(num[a][i]!=num[b][i])
{
return num[a][i]<num[b][i];
}
}
return 0;
}
void work()
{
memset(num,0,sizeof(num));
memset(sum,0,sizeof(sum));
memset(ban,0,sizeof(ban));
L=0;
for(int i=0;i<n;i++)
{
scanf("%s",str);
int len=strlen(str);
if(len>1)
{
ban[str[0]-'a']=1;
}
reverse(str,str+len);
for(int j=0;j<len;j++)//权值总和
{
++num[str[j]-'a'][j];//字母在j位上的出现次数
sum[str[j]-'a']+=power[j];//计算字母权值总和
if(sum[str[j]-'a']>=Q)
sum[str[j]-'a']-=Q;
}
L=max(L,len);//方便后面排序
}
for(int i=0;i<26;i++)//进位操作
{
for(int j=0;j<L;j++)
{
num[i][j+1]+=num[i][j]/26;
num[i][j]%=26;
}
while(num[i][L]){
num[i][L+1]+=num[i][L]/26;
num[i][L++]%=26;
}
a[i]=i;
}
sort(a,a+26,cmp);
int zero=-1;
for(int i=0;i<26;i++)//排除前导为0的情况
{
if(!ban[a[i]])
{
zero=a[i];
break;
}
}
int res=0;
int x=25;
for(int i=25;i>=0;i--)//计算总和答案
{
if(a[i]!=zero)
{
res+=(LL)(x--)*sum[a[i]]%Q;
res%=Q;
}
}
static int ca=0;
printf("Case #%d: %d\n",++ca,res);
}
int main()
{
power[0]=1;
for(int i=1;i<N;i++)//预处理
{
power[i]=(LL)power[i-1]*26%Q;
}
while(scanf("%d",&n)!=EOF)
{
work();
}
return 0;
}
HDU6034Balala Power
最新推荐文章于 2018-03-26 14:28:53 发布