hdu 6034 Balala Power!

题目链接:hdu 6034 Balala Power!

题意:

给你n个字符串,都是包含小写字母,现在让你给a~z赋值0~25,使得这些字符串变成的26进制的数的总和最大。

不能有前导0的情况,他们保证至少有一个字母不出现在第一位。

题解:

每个字符对答案的贡献都可以看作一个 26 进制的数字,问题相当于要给这些贡献加一个 0 到 25 的权重使得答案最大。最大的数匹配 25,次大的数匹配 24,依次类推。排序后这样依次贪心即可,唯一注意的是不能出现前导 0。

前导0的具体处理看代码。

 1 #include<bits/stdc++.h>
 2 #define mst(a,b) memset(a,b,sizeof(a))
 3 #define F(i,a,b) for(int i=(a);i<=(b);++i)
 4 using namespace std;
 5 typedef long long ll;
 6 
 7 const int N=1e5+7,I=1e5,P=1e9+7;
 8 struct node
 9 {
10     int num[N],sz,gei,idx;
11     bool operator <(const node &b)const
12     {
13         for(int i=I;i>=0;i--)
14         {
15             if(num[i]!=b.num[i])return num[i]<b.num[i];
16         }
17         return num[0]<b.num[0];
18     }
19 }a[26];
20 int n,is[26],cas;
21 char s[N];
22 ll fac[N]={1};
23 
24 int main(){
25     F(i,1,I)fac[i]=fac[i-1]*26%P;
26     while(~scanf("%d",&n))
27     {
28         mst(is,0);
29         F(i,0,25)
30         {
31             mst(a[i].num,0);
32             a[i].sz=0,a[i].idx=i;
33             a[i].gei=0;
34         }
35         F(i,1,n)
36         {
37             scanf("%s",s);
38             int len=strlen(s);
39             if(len!=1)reverse(s,s+len);
40             F(j,0,(len-1))
41             {
42                 
43                 if(j==len-1&&len!=1)is[s[j]-'a']=1;
44                 a[s[j]-'a'].num[j]++;
45                 a[s[j]-'a'].sz++;
46                 
47                 while(a[s[j]-'a'].num[j]>=26)
48                 {
49                     a[s[j]-'a'].num[j]-=26;
50                     a[s[j]-'a'].num[j+1]++;
51                 }
52             }
53         }
54         sort(a,a+26);
55         for(int i=25;i>=0;i--)a[i].gei=i;
56         F(i,0,25)if(a[i].sz&&is[a[i].idx]&&a[i].gei==0)
57         {
58             swap(a[i].gei,a[i+1].gei);//处理前导0
59         }else break;
60         ll ans=0;
61         F(i,0,25)if(a[i].sz)
62         {
63             F(j,0,I)if(a[i].num[j])
64             {
65                 ans=(ans+a[i].gei*a[i].num[j]*fac[j])%P;
66             }
67         }
68         printf("Case #%d: %lld\n",++cas,ans);
69     }
70     return 0;
71 }
View Code

 

posted @ 2017-07-25 18:05  bin_gege  阅读(326)  评论(0编辑  收藏  举报