记录每个字母在每个位数出现的次数,直接用结构体记录并排序可能会超时,再建一个新的数组来排序。找出一个没出现在首位(单字母除外)的字母,其它按排序赋值
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100000+10;
const int mod = 1000000007;
int alp[26][N];
int fir[26];
int vis[26];
int num[26];
int cnt = 0;
bool cmp(int a,int b)
{
for(int i = N - 1; i >= 0; i--)
{
if(alp[a][i] > alp[b][i]) return true;
else if(alp[a][i] < alp[b][i]) return false;
}
return false;
}
int main()
{
int n;
int tim = 1;
while(~scanf("%d",&n))
{
char op[N];
memset(alp,0,sizeof(alp));
memset(fir,0,sizeof(fir));
memset(vis,0,sizeof(vis));
memset(num,-1,sizeof(num));
for(int i = 0; i < n; i++)
{
scanf("%s",op);
int len = strlen(op) - 1;
for(int j = 0; j <= len; j++)
{
int d = op[j] - 'a';
if(j == 0 && len > 0)
fir[d] = 1;
alp[d][len - j] ++;
vis[d] = 1;
// cout << d <<" " <<len - j <<" "<<alp[d][len- j]<< endl;
}
}
for(int i = 0; i <= 25; i++)
{
for(int j = 0; j <= N-1; j++)
{
if(alp[i][j] >= 26)
{
alp[i][j+1] += alp[i][j]/26;
alp[i][j] %= 26;
}
}
}
int aa[26];
for(int i = 0; i < 26; i++)
aa[i] = i;
sort(aa,aa+26,cmp);
for(int i = 25; i >= 0; i--)
{
int te = aa[i];
if(!fir[te])
{
num[te] = 0;
break;
}
}
int biap = 25;
for(int i = 0; i <= 25; i++)
{
int te = aa[i];
if(num[te] == -1)
{
num[te] = biap--;
}
}
long long sum = 0;
long long mul = 1;
for(int i = 0; i <= N -1; i++)
{
for(int j = 0; j <= 25; j++)
{
sum = (sum+(alp[j][i]%mod)*(mul*num[j])%mod)%mod;
}
mul *= 26;
mul %= mod;
}
printf("Case #%d: %lld\n",tim++,sum);
}
}