hdu 6034 Balala Power!

119 篇文章 1 订阅
113 篇文章 1 订阅

题目链接:传送门

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 1000000007
typedef 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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值