HDU 6043 (2017 多校训练赛1 1002) Balala Power!


 2017 Multi-University Training Contest - Team 1 1002

Balala Power!



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.  (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 # 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进制时的和最大

    分析:模拟一个26进制的数组p[10010][26] 分别表示每一位每个字母有多少个,当超过26的时候就向前进位
那么可以得到每个字母的权值,将它们的权值从大到小排序,然后赋值
这时候要考虑一个前导0的问题,所以在录入的时候要先标记好哪些字母不能为0
然后将字母按赋值从大到小排序,从小的扫过去,找到第一个可以被赋值为0的,其他的向左推一位

最后将值带入计算就可以了

补充一下坑点:
1 前导0的判断
2 数组要开大一点,计算的时候也要预留几位,因为在进位的时候会超过最大的len(类似于高精度加法)


AC代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define mod 1000000007
using namespace std;
long long num[30];
long long p[100015][30];
long long vis[30];
long long re[100015];
int viss[30];
struct tree
{
    long long t;
    int v;
}Q[30];
struct stree
{
    char anss[100015];
    int v;
}P[30];
bool com(tree a,tree b)
{
    return a.t<b.t;
}
bool com1(tree a,tree b)
{
    return a.t>b.t;
}
bool comq(stree a,stree b)
{
    for(int i=0;i<100015;i++)
    {
        if(a.anss[i]>b.anss[i])
        return 0;
        else if(a.anss[i]<b.anss[i])
        return 1;
    }
}
int main()
{
    re[0]=1;
    for(int i=1;i<100015;i++)
    {
        re[i]=re[i-1]*26;
        re[i]%=mod;
    }
    int n,cas=0;
    while(scanf("%d",&n)==1)
    {
        memset(p,0,sizeof(p));
        memset(num,-1,sizeof(num));
        memset(vis,0,sizeof(vis));
        memset(viss,0,sizeof(viss));
        int len=-1;
        for(int i=0;i<n;i++)
        {
            char a[100015];
            scanf("%s",a);
            int lenn=strlen(a);
            for(int j=0,k=lenn-1;j<lenn;j++,k--)
            {
                viss[a[k]-'a']=1;
                p[j][a[k]-'a']++;
                if(p[j][a[k]-'a']>=26)
                {
                    p[j+1][a[k]-'a']+=p[j][a[k]-'a']/26;
                    p[j][a[k]-'a']=p[j][a[k]-'a']%26;
                }
                if(lenn>1&&j==lenn-1)
                vis[a[k]-'a']=1;
            }
            len=max(len,lenn);
        }
        for(int i=0;i<len+10;i++)
        {
            for(int j=0;j<26;j++)
            {
                if(p[i][j]>=26)
                {
                    p[i+1][j]+=p[i][j]/26;
                    p[i][j]=p[i][j]%26;
                }
            }
        }
        for(int k=0;k<26;k++)
        {
            for(int i=len+10,j=0;i>=0;i--,j++)
            {
                P[k].anss[j]=p[i][k]+'a';
            }
            P[k].v=k;
        }
        sort(P,P+26,comq);
        for(int i=0;i<26;i++)
        {
            if(viss[P[i].v])
            num[P[i].v]=i;
        }
        for(int i=0;i<26;i++)
        {
            Q[i].t=num[i];
            Q[i].v=i;
        }
        sort(Q,Q+26,com);
        for(int i=0;i<26;i++)
        {
            if(vis[Q[i].v])
            num[Q[i].v]++;
            else
            {
                num[Q[i].v]=0;
                break;
            }
        }
        long long ans=0;
        for(int i=0;i<len+10;i++)
        {
            for(int j=0;j<26;j++)
            {
                if(num[j])
                ans+=((num[j]*re[i])%mod)*p[i][j];
                ans%=mod;
            }
        }
        printf("Case #%d: %lld\n",++cas,ans);
    }
}



  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值