2017ACM暑期多校联合训练 - Team 1 1002 HDU 6034 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. (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
题意:
小写字母'a''z'对应于数字025,但是那个字母对应某一个数字这个是不知道的,但是要求一个字母只能唯一的对应一个数字,给定一些字符串,然后将字符串对应的数字表示出来后将这个数字看作26进制来进行转换位10进制,找出一种对应关系使得这些字符串转换后的数字的和最大。还需要注意的一点就是说每一个字符串如果长度大于1的话,那么他的第一个字母表示的数字不能够是0。
分析:
如果不考虑字符串的前导不能为0的话,还是比较好解决的,定义:
num[i][j]:表示字母(i+'a')在第j个位置出现的次数。
bj[i]:表示字母(i+'a')有没有作为首字母出现过。
sum[i]:表示的是字母(i+'a')的所有后面需要呈上的幂次和,因为不管这个字母表示的数字是几,但是因为这个数字没每一个字符串中的位置都不会变化,也就是说它后面需要乘上的那个幂次不会发生变化。
a[26],含义就是说a[i]=j表示i这个数字对应的是字母(j+'a')
了解了这些定义之后呢,集体的看一下解题思路,
因为进行进制转换的时候都是从后往前计算,所以必须将整个的字符串给逆序,这里运用了一个字符串逆序函数(reverse()),逆序中i后我们就可以很好的统计每个字母在任意一个位置出现的次数。
次数统计好之后,我们就要考虑如何给每一个字母对应值了,能想到的肯定是如果某一个字母它的最高位置越大,那么这个字母所表示的数字应该越大,那么如果说两个字母的最高位置是一样的呢?那么我就就要接着往下比较他们的次高位置,还是一样的道理,一直往下比较下去直到它们在同一个位置出现的次数不一样为止。这些字母是在数组a中进行排序的,拍好后就是这些字母对应的小到大的顺序。
然后我们考虑前导字母表示的数字不能够为数字0,(出现在这种情况也就意味着26个字母都出现了)。这样我们肯定能够在非前导中找到一个对应的数字最小的,然后将它对哦赢得数组看作0,然后其余的对应的数字小于该数字的所有字母对应的数字依次向前对应一位。
代码:(附详细注释)
#include<stdio.h>
#include<iostream>
#include<string.h>
#include <algorithm>
const int L=100020;
const int mod=1e9 + 7;
typedef long long ll;
using namespace std;
int num[26][L];///num[i][j]表示第i个字母在位置j出现的次数
int bj[26];///标记字母有没有在首位出现
int Mi[L],sum[L];///分别表示26的幂和某一个字母总共的次方和
int max_len=-1;
int n,Case=0;;
char str[L];///保存输入的字符串
int a[26];///含义就是说a[i]=j表示i这个数字对应的是字母(j+'a')
void inif()///所有的数组完成一个初始化的功能
{
memset(num,0,sizeof(num));
memset(bj,0,sizeof(bj));
memset(sum,0,sizeof(sum));
}
///这个排序也就是相当于将每一个字母所对应的数字按照从小到大的顺序排好
bool cmp(int n1,int n2)/// 用n1,n2分别表示的是两个字母(该字母可以表示为n1+'a',n2+'a'),并不是他们所对应的数字
{
for(int i=max_len-1; i>=0; i--)
{
if(num[n1][i]!=num[n2][i])
return num[n1][i]<num[n2][i];///然后按照这两个字母在同一个位置出现次数按照从小到大排序
}
return 0;
}
void solve()
{
inif();
for(int i=0; i<n; i++)
{
scanf(" %s",str);
int len=strlen(str);
if(len>1)
bj[str[0]-'a']=1;
reverse(str , str + len);///字符串倒置,就是将整个字符串的位置颠倒过来
for(int j=0; j<len; j++)
{
num[str[j]-'a'][j]++;///该字母在当前位出现的次数加加
sum[str[j]-'a']+=Mi[j];
/*
最开始的时候不理解这里是什么意思,就是说不管一个字母表示的数字如何变化,但是它所在的位数是不会
变化的,也就是说它后面需要乘上的26的几次方不会发生变化
*/
if(sum[str[j]-'a']>=mod)
sum[str[j]-'a']%=mod;
}
max_len=max(len,max_len);
}
for(int i=0; i<26; i++)
{
for(int j=0; j<max_len; j++)
{
num[i][j+1]+=num[i][j]/26;
num[i][j]%=26;
}
while(num[i][max_len])///是说最高位上的某个字母的个数已经超过26了,为了计算方便则向前进一位
{
num[i][max_len+1]=num[i][max_len]/26;///看能不能向前进一位
num[i][max_len]%=26;///保留当前位上的个数
max_len++;///字符串总长度及加
}
a[i]=i;///表示的是当前字母所对应的数字,暂时先这样定义,也相当于一个初始化过程
}
sort(a,a+26,cmp);///关键在于看懂这个函数的排序规则,排完之后就是每一个字母所对应的数字了
int ans=-1;
for(int i=0; i<26; i++)
{
if(!bj[a[i]])
{
ans=a[i];
break;
}
}
int res=0,x=25;
for(int i=25; i>=0; i--)
{
if(a[i]!=ans)
{
// printf("%d %d\n",a[i],sum[a[i]]);
res+=(ll)(x--)*sum[a[i]]%mod;///只有这个字母出现过,sum[a[i]]才有值
res%=mod;
}
}
printf("Case #%d: %d\n",++Case,res);
}
int main()
{
Mi[0]=1;
for(int i=1; i<L; i++)
{
Mi[i]=(ll)Mi[i-1]*26%mod;
//printf("%d\n",Mi[i]);
}
while(~scanf("%d",&n))
{
solve();
}
}
2017ACM暑期多校联合训练 - Team 1 1002 HDU 6034 Balala Power! (字符串处理)的更多相关文章
- 2017ACM暑期多校联合训练 - Team 8 1002 HDU 6134 Battlestation Operational (数论 莫比乌斯反演)
题目链接 Problem Description The Death Star, known officially as the DS-1 Orbital Battle Station, also k ...
- 2017ACM暑期多校联合训练 - Team 7 1002 HDU 6121 Build a tree (深搜+思维)
题目链接 Problem Description HazelFan wants to build a rooted tree. The tree has n nodes labeled 0 to n− ...
- 2017ACM暑期多校联合训练 - Team 6 1001 HDU 6096 String (字符串处理 字典树)
题目链接 Problem Description Bob has a dictionary with N words in it. Now there is a list of words in wh ...
- 2017ACM暑期多校联合训练 - Team 6 1002 HDU 6097 Mindis (数学)
题目链接 Problem Description The center coordinate of the circle C is O, the coordinate of O is (0,0) , ...
- 2017ACM暑期多校联合训练 - Team 4 1004 HDU 6070 Dirt Ratio (线段树)
题目链接 Problem Description In ACM/ICPC contest, the ''Dirt Ratio'' of a team is calculated in the foll ...
- 2017ACM暑期多校联合训练 - Team 9 1005 HDU 6165 FFF at Valentine (dfs)
题目链接 Problem Description At Valentine's eve, Shylock and Lucar were enjoying their time as any other ...
- 2017ACM暑期多校联合训练 - Team 9 1010 HDU 6170 Two strings (dp)
题目链接 Problem Description Giving two strings and you should judge if they are matched. The first stri ...
- 2017ACM暑期多校联合训练 - Team 8 1006 HDU 6138 Fleet of the Eternal Throne (字符串处理 AC自动机)
题目链接 Problem Description The Eternal Fleet was built many centuries ago before the time of Valkorion ...
- 2017ACM暑期多校联合训练 - Team 8 1011 HDU 6143 Killer Names (容斥+排列组合,dp+整数快速幂)
题目链接 Problem Description Galen Marek, codenamed Starkiller, was a male Human apprentice of the Sith ...
随机推荐
- PokeCats开发者日志(十四)——终章
已经不知道离PokeCats游戏开始开发有多少个晚上了,今晚心血来潮整理随笔的时候发现这个故事还没有划上句号. 故事的结局是最终我拿到了软著权,但是没办法上架到任何一个知名的安卓app市场,连 ...
- Python2爬虫获取的数据存储到MySQL中时报错"Incorrect string value: '\\xE6\\x96\\xB0\\xE9\\x97\\xBB' for column 'new' at row 1"的解决办法
由于一直使用python3进行编码,在使用Python2时,将爬虫数据连接数据库进行存储时,出现如上的报错,经查资料 是数据库编码问题. 如下转自:http://www.cnblogs.com/liu ...
- [剑指Offer] 47.求1+2+3+...+n
题目描述 求1+2+3+...+n,要求不能使用乘除法.for.while.if.else.switch.case等关键字及条件判断语句(A?B:C). [思路]用&&的短路思想来求和 ...
- IE8 兼容CSS3 使用 PIE.htc
在需要的标签中 div { border:; border-bottom: 10px solid transparent; border-image: url(../images/border-img ...
- asp.net异步上传
界面如下:
- matlab eval【转】
Matlab 简单谈谈EVAL函数的用法 EVAL(s)相当于把字符串s的内容作为语句来执行. 比如:eval('a=3*5') 和直接在command 窗口中输入 a=3*5 等效 eval 一个经 ...
- uva1086 The Ministers' Major Mess
题意:有n 个议案,m 个大臣,每个大臣会对其中的ki 个议案投票,为赞成或反对.现要你判断是否存在一种方案,使得每个大臣有大于一半的投票被满足.若存在,还需判断某个议案是不是一定要通过,或者一定不能 ...
- OpenStack Queens版本Horizon定制化开发
工具环境 1.VMware workstation 12+: 2.Ubuntu系统+Linux Pycharm: 3.OpenStack Queens版本Horizon代码: 问题及解决 1.项目代码 ...
- BZOJ2337:[HNOI2011]XOR和路径——题解
+++++++++++++++++++++++++++++++++++++++++++ +本文作者:luyouqi233. + +欢迎访问我的博客:http://www.cnblogs.com/luy ...
- webpack css压缩方案
css-loader原有的minimize选项在1.0.0版本已经移除,不能使用其进行css压缩. 目前可行的css压缩方案有: 1. postcss-loader with cssnano or u ...