Problem Description
Talented Mr.Tang has n strings consisting of only lower case characters. He wants to charge them with Balala Power (he could change each character ranged from a to z into each number ranged from 0 to 25, but each two different characters should not be changed into the same number) so that he could calculate the sum of these strings as integers in base 26 hilariously.
Mr.Tang wants you to maximize the summation. Notice that no string in this problem could have leading zeros except for string “0”. It is guaranteed that at least one character does not appear at the beginning of any string.
The summation may be quite large, so you should output it in modulo 109+7 .
Input
The input contains multiple test cases.
For each test case, the first line contains one positive integers n, the number of strings. (1≤n≤100000)
Each of the next n lines contains a string si consisting of only lower case letters. (1≤|si|≤100000,∑|si|≤106)
Output
For each test case, output “Case #x: y” in one line (without quotes), where x indicates the case number starting from 1 and y denotes the answer of corresponding case.
Sample Input
1
a
2
aa
bb
3
a
ba
abc
Sample Output
Case #1: 25
Case #2: 1323
Case #3: 18221
题目大意
有 n 个字符串,字母a~z对应着0~25的权值,每种字母拥有自己不同的权值,且转化为权值后仍然是26进制的表示,求转化为10进制之后的最大值。
解题思路
肆虐的表情包也平复不了自己WA了那么多次的心情--,明白了题意,知道了解题思路,敲出了代码,搞过了各种数据,还是WA,自己敲的坑自己填--,吐槽完毕!
首先很容易想到让出现位置越高,出现频率越大的字母分到的权值越大(贪心思想),于是在输入的过程中统计字符串所包含字母在相应位置上出现的次数,当某一位置的次数满 26 时,需要向高位置进1,该位置修改为0(因为是26进制);
另外注意除了含有单个字符的字符串之外,其他字符串不可以出现前导0,如果存在这种情况,就需要由可为0的字符进行代替,但并不是交换,因为为了保证最后结果的最大化,是将本来权值为[0,mark-1]的权值增加 1 (标记可为 0 字符的权值为 mark)。
代码实现
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 100007
#define ll long long
const int mod=1e9+7;
bool ff[26];
struct node
{
int index;
int num[maxn];
} point[26];
bool cmp(const node &a,const node &b)
{
for(int i=maxn-1; i>=0; i--)
{
if(a.num[i]!=b.num[i])
return a.num[i]<b.num[i];
}
return false;
}
int main()
{
int n,cas=0,mark;
char str[maxn];
while(~scanf("%d",&n))
{
for(int i=0; i<26; i++)
{
point[i].index=i;
memset(point[i].num,0,sizeof(point[i].num));
}
memset(ff,0,sizeof(ff));
while(n--)
{
scanf("%s",str);
int len=strlen(str);
if(len>1) ff[str[0]-'a']=1;
for(int i=0; i<len; i++)
{
int j=len-i-1;
point[str[i]-'a'].num[j]++;
while(point[str[i]-'a'].num[j]==26)
{
point[str[i]-'a'].num[j]=0;
point[str[i]-'a'].num[++j]++;
}
}
}
sort(point,point+26,cmp);
for(int i=0;i<26;i++)
if(!ff[point[i].index])
{
mark=i;
break;
}
ll ans=0;
for(int i=25; i>=0; i--)
{
ll cnt=0;
for(int j=maxn-1; j>=0; j--)
{
cnt=(cnt*26%mod+point[i].num[j]%mod)%mod;
}
ans=(ans+(cnt*(i==mark?0:i<mark?i+1:i))%mod)%mod;
}
printf("Case #%d: %lld\n",++cas,ans);
}
return 0;
}
PS: WA到最后还是怂了,参考了千神的题解
贴贴贴:
http://blog.csdn.net/qq_28954601/article/details/76129862