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-56.两数之和
两数之和 给一个整数数组,找到两个数使得他们的和等于一个给定的数 target. 你需要实现的函数twoSum需要返回这两个数的下标, 并且第一个下标小于第二个下标.注意这里下标的范围是 1 到 n, ...
- IIS10和Tomcat8整合
在网上找了很久,也试了很多,都没有弄好.后来根据这个博客,做一些小修小改,终于成功了. 我是从里面的IIS与TOMCAT整合那里开始看的.第一步上面要创建一个注册表,我没有创建.我是创建了一个名为&q ...
- 常见设备在linux中的文件名
设备 linux中的文件名 IDE硬盘 /dev/hd[a-d] SATA/USB/SCSI/SAS /dev/sd[a-p] 软盘 /dev/fd[0-1] 打印机 25针:/dev/lp[0-2] ...
- bpf程序
bpf都是怎么起作用的? 记得bpf之前是绑定在bpf bpf作用在哪里呀?
- [剑指Offer] 56.删除链表中重复的结点
题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后 ...
- 【swaggerui】swaggerui在asp.net web api core 中的应用
Swaggerui 可以为我们的webapi提供美观的在线文档,如下图: 实现步骤: NuGet Packages Install-Package Swashbuckle.AspNetCore 在s ...
- HDFS文件操作命令手册
HDFS文件操作的基本格式是: bin/hadoop dfs -cmd <args> 1. cat $ hadoop dfs -cat URI [URI …] #将参数所指示的文件的内容输 ...
- Andorid API Package --->android.animation
包名: android.animation Added in API level 11 URL:http://developer.andr ...
- BZOJ3052 & UOJ58:[WC2013]糖果公园——题解
http://uoj.ac/problem/58 http://www.lydsy.com/JudgeOnline/problem.php?id=3052 输入格式 输出格式 input 4 3 5 ...
- 洛谷1578:[WC2002]奶牛浴场——题解
https://www.luogu.org/problemnew/show/P1578#sub 由于John建造了牛场围栏,激起了奶牛的愤怒,奶牛的产奶量急剧减少.为了讨好奶牛,John决定在牛场中建 ...