HDU-6034 Balala Power!(贪心)

Balala Power!

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


 

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

 

 

Source

2017 Multi-University Training Contest - Team 1

 

 

Recommend

liuyiding

题目:给n个字符串中出现的小写英文字母赋值,赋值为0~25,规则是 同一个字母只能是一个值,不同的字母不能是相同值,赋值之后不能有前导零,看起来就像是26进制的数字,求出最大的赋值结果转化为十进制输出。

思路:一开始的思路是把每一个字母在所有的字符串中出现的位置存起来,算出这些位置表示的十进制数值,最后排序按从大到校给每一个字符赋从25到0的值,但是由于要取模,所以算完十进制在取完模之后,本来最大的可能会变小。所以应该直接按照每个字母出现的位置的26进制数值从大到小排序,然后在赋值。小细节是判断一下会不会有前导零。

#include<map>
#include<set>
#include<queue>
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
#define inf 0x3f3f3f3f
const int mod=1e9+7;
const int maxn=100000+5;
char s[maxn];
map<int,int>m;
int a[100][maxn];
int odr[100];
int mlen;
int vis[300],squ[300];
ll pow_mod(ll a,ll b,ll c){
    a=a%c;
    ll ans=1;
    while(b){
        if(b&1)
            ans=(ans*a)%c;
        a=(a*a)%c;
        b>>=1;
    }
    return ans%c;
}
bool cmp(int aa,int b){
    for(int i=maxn-1;i>=0;i--){
        if(a[aa][i]!=a[b][i]){
            return a[aa][i]>a[b][i];
        }
    }
    return false;
}
int main(){
    int n;
    int t=0;
    while(~scanf("%d",&n)){
        mem(a,0);
        mem(vis,0);
        mem(odr,0);
        for(int i=0;i<26;i++)squ[i]=inf;
        int y=0;mlen=0;
        for(int i=0;i<n;i++){
            scanf("%s",s);int len=strlen(s);
            for(int j=0;j<len;j++){
                char loc=s[j];
                if(vis[loc]==0){
                    vis[loc]=1;
                    odr[y]=loc-'a';
                    y++;
                }
                if(len>1)squ[loc-'a']=min(squ[loc-'a'],j);
                a[loc-'a'][len-j-1]++;
            }
       }
       for(int i=0;i<26;i++){
        for(int j=0;j<maxn;j++){
            a[i][j+1]+=a[i][j]/26;
            a[i][j]%=26;
            }
       }
       sort(odr,odr+y,cmp);
       int flag=25;
        ll ans=0;
        if(y<25){
           for(int i=0;i<y;i++){
            int x=odr[i];
            for(int j=maxn-1;j>=0;j--){
                if(a[x][j]!=0){
                    ans+=pow_mod(26,j,mod)*a[x][j]*flag;
                    ans%=mod;
                }
            }
            flag--;
           }
        }
        else {
            int p=y-1;
            while(squ[odr[p]]==0)p--;
            for(int i=0;i<y;i++){
                    if(i==p)continue;
                    int x=odr[i];
                for(int j=maxn-1;j>=0;j--){
                    if(a[x][j]!=0){
                    ans+=pow_mod(26,j,mod)*a[x][j]*flag;
                    ans%=mod;
                    }
                }flag--;
            }
        }
        printf("Case #%d: %lld\n",++t,ans);
    }
}
/*
1
abcdefghijklmnopqrstuvwxyz
Case #1: 734910456
*/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值