HDU 6034 Balala Power!

来源:互联网 发布:mac os 11.12 cdr 编辑:程序博客网 时间:2024/06/07 02:26

题目

Balala Power!

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


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 toz 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. (1n100000)

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 #xy" 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

题目大意


        给你n个字符串,你可以把字母转换成0-25之中的一个数,但是两个不同的字母不会变成同一个数,并且第一个字母不能变成0除了该字符串只有一个字符的时候,题目保证一定不会出现所有字符都无法当0的情况

       要你求出组成的26进制的数最大是多少


解题思路


      本题我们最重要的事就是给字母赋值,我们想给权值最大的字母赋值最大的25其他的再依次赋值24,23.....,为了达到这个目的,我们就需要开一个num[30][1e5]统计每一个字母在字符串的每一位出现的次数,把它变成类似于高精度那样,我们做高精度就是用的数组模拟,这样利用数组我们就可以把字母看成可以比较的值了,例如样例的(3 a ba abc)  a在百位出现一次,个位出现一次,b在十位出现两次,c在个位出现一次 这样统计出来我们就可以对字母的出现次数进行类似于自然数的排序方式进行排序,得知 a赋值25 b赋值24 c赋值23 

      本题需要处理一下前导零的问题,所以需要在输入的时候进行一下处理,标记字母是否可以是0,如果不能是零但是最后赋值成了0,这个0应该转移给可以是零的字母里面赋值最小的那个字母,这里只需要给这个字母标记一下,在赋值的时候把这个字母直接跳过(因为是0,跳过就相当于赋值0了)就可以了。

      具体写法,看一下代码吧,自己刚开始写的思路对,但是代码优化程度还是很差,看了标程以后把自己的代码向着标程方向改的。

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>using namespace std;#define LL long longconst int mod=1000000000+7;const int maxn=1000000+10;int num[30][maxn];LL sum[30];LL mypow[maxn];int ran[30],mlen,case_=1,n;bool lead[30];char str[maxn];bool cmp(int x,int y){    for(int i=mlen-1;i>=0;i--)    {        if(num[x][i]!=num[y][i])            return num[x][i]<num[y][i];    }    return 0;}void Init(){    mypow[0]=1;    for(int i=1;i<maxn;i++)        mypow[i]=mypow[i-1]*26%mod;}void work(){        memset(num,0,sizeof(num));        memset(sum,0,sizeof(sum));        memset(lead,0,sizeof(lead));        mlen=0;        for(int i=0;i<n;i++)        {            scanf("%s",str);            int len=strlen(str);            if(len>1)                lead[str[0]-'a']=1;//lead数组标记是否可以为零,1不可以,0可以             if(len>mlen)                mlen=len;            reverse(str , str + len);//字符串反转            for(int i=0;i<len;i++)            {                num[str[i]-'a'][i]++;                sum[str[i]-'a']+=mypow[i];                if(sum[str[i]-'a']>=mod)                {                    sum[str[i]-'a']%=mod;                }            }        }        for(int i=0;i<=25;i++)        {            ran[i]=i;//排名数组进行初始化,ran数组代表赋值大小的顺序的数组,ran[0]代表的字母数赋值0,ran[1]代表的字母赋值1......ran[25]代表的字母赋值25            for(int j=0;j<mlen;j++)            {                num[i][j+1]+=num[i][j]/26;                num[i][j]%=26;            }            while(num[i][mlen])            {                num[i][mlen+1]=num[i][mlen]/26;                num[i][mlen++]%=26;            }        }        sort(ran,ran+26,cmp);        int zero=-1;//初始化,防止不需要考虑前导零的时候sero在0-25之间出现错误        for(int i=0;i<26;i++)        {           if(!lead[ran[i]])//可以当零           {               zero=ran[i];               break;           }        }        LL ans=0;        int x=25;        for(int i=25;i>=0;i--)        {            if(ran[i]!=zero)           {                ans=(ans+((LL)(x--)*sum[ran[i]])%mod)%mod;                ans%=mod;           }        }        printf("Case #%d: %lld\n",case_++,ans);}int main(){    Init();    while(~scanf("%d",&n))    {       work();    }    return 0;}




原创粉丝点击