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 ...
随机推荐
- lintcode-13-字符串查找
字符串查找 对于一个给定的 source 字符串和一个 target 字符串,你应该在 source 字符串中找出 target 字符串出现的第一个位置(从0开始).如果不存在,则返回 -1. 说明 ...
- textarea怎么解析html代码,从而实现一个可高亮的输入框
效果: 思路: 让一个div浮动在textarea上,样式和位置保持完全一致,textarea负责输入,div负责高亮显示 代码: .vue <template> <div clas ...
- 关于c中的一些新函数
localtime 和 localtime_s: localtime:localtime(const time_t * _Time) time_t t;struct tm *local;time(&a ...
- mysql学习之主从复制
该文使用mysql5.5 centos6.5 64位 一.主从复制的作用 1.如果主服务器出现问题,可以快速切换到从服务器. 2.对与实时性要求不高或者更新不频繁的应用可以在从服务器上执行查询操作,降 ...
- InnoDB,select为啥会阻塞insert?
MySQL的InnoDB的细粒度行锁,是它最吸引人的特性之一. 但是,如<InnoDB,5项最佳实践>所述,如果查询没有命中索引,也将退化为表锁. InnoDB的细粒度锁,是实现在索引记录 ...
- 【Python】Python中的引用和赋值
本文转自:http://my.oschina.net/leejun2005/blog/145911 在 python 中赋值语句总是建立对象的引用值,而不是复制对象.因此,python 变量更像是指针 ...
- 在网页中显示器PDF文档
<iframe src="></iframe> 在需要显示的页面中添加上面语句就可以.
- 2.StringBuffer:线程安全的可变字符串序列
一.String.StringBuffer和StringBuilder的区别 1.String是内容不可变的,而StringBuffer和StringBuilder都是内容可变的. 2.StringB ...
- Android UI设计的基本元素有哪些
在android app开发如火如荼的今天,如何让自己的App受人欢迎.如何增加app的下载量和使用量....成为很多android应用开发前,必须讨论的问题.而ui设计则是提升客户视觉体验度.提升下 ...
- python函数调用关系图(python call graph)
由于要重构项目的部分代码,要整理好主要的函数调用关系,不想自己看代码慢慢画出结构,想找出一种通用的,节省人力的方法得出函数间的调用关系图,于是发现以下几个工具.(内网没装好graphviz,还没真正用 ...