hdu 6034 Balala Power!

来源:互联网 发布:手机淘宝详情优惠券 编辑:程序博客网 时间:2024/05/24 02:33

题目链接:传送门

Balala Power!
这里写图片描述
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 5833 Accepted Submission(s): 1475

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),但是每个字符串赋值之后,不能出现前导零,问n个字符串的和是多少?

思路:记录每一个字符在不同位置的个数(因为数值较大,爆long long,所以只能这样判断大小),再记录他们的价值。

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define N 100020#define mod 1000000007typedef long long LL;int num[26][N];//记录不同字符在不同位置的个数,用于比较大小int sum[N];//记录每个字符的总价值int xia[26];//判断这个字符是否可以为零int a[26];//排序时用到char ch[N];int val[N];//记录不同位置的价值int L;//记录字符串的最大长度void doo()//打印不同位置的价值{    val[0]=1;    for(int i=1;i<=N;i++)        val[i]=(long long)val[i-1]*26%mod;}bool cmp(int x,int y)//比较大小,字符总价值小的在前{    for(int i=L-1;i>=0;i--)    {        if(num[x][i]!=num[y][i])            return num[x][i]<num[y][i];    }    return 0;}int main(){    int n,t=1;    doo();//打印不同位置的价值    while(~scanf("%d",&n))    {        memset(num,0,sizeof(num));        memset(xia,0,sizeof(xia));        memset(sum,0,sizeof(sum));        L=0;        for(int i=0;i<n;i++)        {            scanf("%s",ch);            int l=strlen(ch);            L=max(L,l);            if(l>1)//记录该字符不能为零                xia[ch[0]-'a']=1;            reverse(ch,ch+l);//前后颠倒            for(int j=0;j<l;j++)            {                int x=ch[j]-'a';                num[x][j]++;                sum[x]=(sum[x]+val[j])%mod;            }        }        for(int i=0;i<26;i++)//不同字符在不同位置的个数,将他们进位        {            a[i]=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+1]+num[i][L]/26;                num[i][L++]%=26;            }        }        sort(a,a+26,cmp);//排序        int f=-1;        for(int i=0;i<26;i++)        {            if(xia[a[i]]==0)            {                f=a[i];                break;            }        }        int sun=0;        int p=25;        for(int i=25;i>=0;i--)//赋值(0-25)过程        {            if(a[i]!=f)            {                sun+=(long long)sum[a[i]]*p%mod;                p--;                sun%=mod;            }        }        printf("Case #%d: %d\n",t++,sun);    }    return 0;}