您的位置:首页 > 大数据 > 人工智能

hdu 6034 Balala Power!(贪心)( 2017 Multi-University Training Contest - Team 1 )(无耻之sort)

2017-07-26 09:48 627 查看

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
4000
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可以任意变为0~25中的任意数,不同字母映射的值不能相同,给你n串字符串,

问把这些字符串中的字母转换成(26进制)数字后,能够得到的最大的和是多少

(字符串转换后的数字不能有前缀0,除了”0”)

思路:

很明显,肯定要先对a~z这26个字母排序,然后依次从25开始赋值了。

根据什么来排序呢,(直接求和得到的)权值?不行,爆longlong

但是我们可以转换一下,依然是求和,我们可以用数组来表示权值的每一位

p[x].num[i]表示字母(x+‘’a’)的第i位为多少

接着则可比较num[i]来对字母进行排序,排好序后赋值,计算即可(具体详见代码)

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

typedef long long LL;
const int mod=1e9+7;
const int N=1e5+10;

struct node
{
int val;
int num
;//num[i]表示第i位上存在多少个val
} q[27];

char str
;
bool inq[30],vis[30];//vis记录出现的字母,inq记录哪些字母不能为0
int mp[30];
LL table
;
int n,ps;//ps为字符串最长的长度

bool cmp(node a,node b)
{
for(int i=ps+9; ~i; --i)
if(a.num[i]!=b.num[i])
return a.num[i]>b.num[i];
return 0;
}

void Table()//26的次方打表
{
table[0]=1;
for(int i=1; i<N; ++i)
table[i]=(table[i-1]*26)%mod;
}

void init()//初始化
{
memset(mp,0,sizeof(mp));
memset(inq,false,sizeof(inq));
memset(vis,false,sizeof(vis));
for(int i=0; i<26; ++i)
{
q[i].val=i;
memset(q[i].num,0,sizeof(q[i].num));
}
ps=0;
}

int main()
{
Table();
int t=0;
while(~scanf("%d",&n))
{
init();
for(int i=0; i<n; ++i)
{
scanf("%s",str);
int len=strlen(str);
if(len>1)//不能为0
inq[(str[0]-'a')]=1;
for(int j=0; j<len; ++j)
{
int x=str[j]-'a',y=len-j-1;
vis[x]=1;
q[x].num[y]+=1;
}
ps=max(ps,len);
}
for(int i=0; i<ps+10; ++i)//满26进1,处理进位
for(int j=0; j<26; ++j)
{
q[j].num[i+1]+=q[j].num[i]/26;
q[j].num[i]%=26;
}
sort(q,q+26,cmp);
int flag=-1;//记录为0的那个字母
if(vis[q[25].val])//如果26个字母全存在,说明必要有字母为0
{
for(int i=25; ~i; --i)
{
int x=q[i].val;
if(!inq[x])//将(x+'a')置为0
{
mp[x]=0;
flag=x;
break;
}
}
}
int tot=25;
for(int i=0; i<26; ++i)//依次给字母赋权值
{
int x=q[i].val;
if(vis[x])
{
if(x!=flag)
mp[x]=tot--;
}
else
break;
}
LL ans=0;
for(int i=0; i<ps+10; ++i)
for(int j=0; j<26; ++j)
{
int x=q[j].val;
if(vis[x])
ans=(ans+(mp[x]*table[i]%mod)*q[j].num[i])%mod;
}
printf("Case #%d: %lld\n",++t,ans);
}
return 0;
}


ps:这道题考察的纯粹是sort。。

比赛时也用了这种方法,但是一运行程序输入数据就直接崩溃,最后gg了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐