HDU-Balala Power!

来源:互联网 发布:智能后视镜安装软件 编辑:程序博客网 时间:2024/06/03 17:49

HDU-Balala Power!

Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 5512 Accepted Submission(s): 1398

这里写图片描述

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

1a2aabb3abaabc

Sample Output

Case #1: 25Case #2: 1323Case #3: 18221

代码:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>using namespace std;typedef long long LL;   /// 用LL来替换long longconst int N = 100020;const int Q = 1e9 + 7;int n, L;int num[26][N];       ///sum一维下标存该字母减去‘a’的ASCLL码,也就是该字母元素///二维数组下标存该字母元素的位置,数组里存该字母元素出现的个数int power[N], sum[N];     ///power数组存对应位的权值,sum数组存相同字母对应位的权值总和bool ban[26];      ///作为标记数组,将出现在开头的字母作标记char str[N];int a[26];       ///用来映射每个字母所代表的值bool cmp(int A, int B)      ///排序依据是num存的字母从高位到低位个数的多少{    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(ban, 0, sizeof(ban));    memset(sum, 0, sizeof(sum));    L = 0;    for (int i = 0 ; i < n ; ++ i)    {        scanf("%s", str);        int len = strlen(str);        if (len > 1)        ///如果字符串长度大于1,则标记该字符串首字母不能为0        {            ban[str[0] - 'a'] = 1;        }        reverse(str, str + len);      ///将字符串str倒置        for (int j = 0 ; j < len ; ++ j)        {            ++ num[str[j] - 'a'][j];     ///存字母出现的次数            sum[str[j] - 'a'] += power[j];      ///求出现的字母的所有权值            if (sum[str[j] - 'a'] >= Q)      ///如果sum里的数超过了Q,则对它取余            {                sum[str[j] - 'a'] -= Q;            }        }        L = max(L, len);       ///保存输入字符串的最大长度    }    for (int i = 0 ; i < 26 ; ++ i)    {        for (int j = 0 ; j < L ; ++ j)        {            ///处理元素i个数的进位情况            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;    ///对a数组进行赋初值    }    sort(a, a + 26, cmp);        ///对a数组排序,排序后a数组内容代表字母,下标代表字母所代表    int zero = -1;    for (int i = 0 ; i < 26 ; ++ i )    {        if (!ban[a[i]])     ///找到最小的可以为0的字母        {            zero = a[i];            break;        }    }    int res = 0, 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;          ///初始化power数组,个位的权值为26^0=1    for (int i = 1 ; i < N ; ++ i)    {        ///依次用低一位的权值*26得到高一位的权值,然后对10^9+7取模        power[i] = (LL)power[i - 1] * 26 % Q;    }    while (~scanf("%d", &n))    {        work();    }    return 0;}
原创粉丝点击