题意:给你许多字符串,让你给这些字母赋值(0-25),把字符串转化成26进制数,不能有前导0,但可以是“0”。求累加和
思路:把字母在哪一位都记下来,开始我是用num数组,把这些字母直接累加26^cnt (cnt为第几位),这num显然是要炸得,WA了十几遍。正解应该是把字母的位数都存下来,num[26][100005]。满26就进位。最大的乘25,依次减少。
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<stdlib.h>
#include<math.h>
#include<vector>
#include<list>
#include<map>
#include<stack>
#include<queue>
#include<algorithm>
#include<numeric>
#include<functional>
using namespace std;
const int maxn = 1e5+5;
const long long MOD = 1e9+7;
char s[maxn];
long long num[30][maxn],f[maxn];
int vis[30],pai[30];
void getf()
{
f[0] = 1;
for(int i = 1; i <= maxn-1; i++)
f[i] = f[i-1] * 26 % MOD;
}
int cmp(const int &x,const int &y)
{
for(int i = maxn-1; i >= 1; i--)
{
if(num[x][i] != num[y][i])
{
return num[x][i] > num[y][i];
}
}
return num[x][0] > num[y][0];
}
int main()
{
int i,j,k,n,kase = 1;
getf();
while(scanf("%d",&n)!=EOF)
{
memset(num,0,sizeof num);
memset(vis,-1,sizeof vis);
while(n--)
{
scanf("%s",s);
int len = strlen(s);
if(len > 1)
vis[s[0]-'a'] = 0;
for(i = 0; i < len; i++)
{
int cnt = len - i - 1;
int x = s[i] - 'a';
num[x][cnt]++;
while(num[x][cnt] == 26)
{
num[x][cnt] = 0;
num[x][++cnt]++;
}
}
}
for(i = 0; i < 26; i++)
pai[i] = i;
sort(pai,pai+26,cmp);
int flag;
for(i = 25; i >= 0; i--)
{
if(vis[pai[i]] == -1)
{
flag = i;
break;
}
}
long long tp = 25ll,ans = 0ll;
for(i = 0; i < 26; i++)
{
if(i == flag) continue;
for(j = maxn-1; j >= 0; j--)
{
ans += ( ( tp * num[pai[i]][j] % MOD ) * f[j] ) % MOD;
ans %= MOD;
}
tp--;
}
printf("Case #%d: %lld\n",kase++,ans);
}
return 0;
}