首页 > 代码库 > hdu 6034 Balala Power!
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 }
hdu 6034 Balala Power!
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。