传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6034
题意:
给出 N 个字符串,要求我们对每个字符映射成 0~25中的一个数字,要求最后所有字符串转换为26进制能得到的最大值。
解题思路:
统计每个字符在每一位上得贡献(用数组模拟26进制),然后按照这个模拟得26进制诸位比较, 贪心映射;
但是注意一个点就是不能出现前缀 0 的情况,所以我们要标记哪种字符可以作为前缀0哪种不可以,排序完后处理一下不满足前缀 0 的情况,最后暴力答案即可;
AC code:
1 #include<bits/stdc++.h> 2 #define LL long long 3 using namespace std; 4 const int maxn = 1e5+7; 5 const int mod = 1e9+7; 6 struct node{ 7 int len[maxn]; 8 int w; 9 int v; 10 int L; 11 }p[26]; 12 int n; 13 string s[maxn]; 14 bool vis[26]; 15 int flag[26]; 16 int mmp[26]; 17 int cas = 0; 18 bool cmp(node A,node B){ 19 if(A.L!=B.L)return A.L<B.L; 20 for(int i=A.L;i>=0;i--){ 21 if(A.len[i]==B.len[i])continue; 22 return A.len[i]<B.len[i]; 23 } 24 return 0; 25 } 26 int main(){ 27 while(cin>>n){ 28 cas++; 29 memset(vis, 0, sizeof(vis)); 30 memset(flag,0,sizeof(flag)); 31 for(int i=0;i<26;i++){ 32 for(int j=0;j<=p[i].L;j++){ 33 p[i].len[j]=0; 34 } 35 } 36 for(int i=0;i<26;i++){ 37 p[i].v=0; 38 p[i].w=i; 39 p[i].L=-1; 40 } 41 for(int i=0;i<n;i++){ 42 cin>>s[i]; 43 if(s[i].size()>1){ 44 flag[s[i][0]-'a']++; 45 } 46 reverse(s[i].begin(),s[i].end()); 47 for(int j=0;j<s[i].size();j++){ 48 p[s[i][j]-'a'].len[j]++; 49 vis[s[i][j]-'a'] = 1; 50 } 51 } 52 for(int i=0;i<26;i++){ 53 for(int j=0;j<maxn-1;j++){ 54 if(p[i].len[j]>=26){ 55 int d = p[i].len[j]/26; 56 p[i].len[j]%=26; 57 p[i].len[j+1]+=d; 58 } 59 if(p[i].len[j]>0){ 60 p[i].L=max(p[i].L,j); 61 } 62 } 63 } 64 sort(p,p+26,cmp); 65 // puts("zjj"); 66 67 for(int i=0;i<26;i++){ 68 p[i].v=i; 69 } 70 for(int i=0;i<26;i++){ 71 if(flag[p[i].w]&&p[i].v==0){ 72 swap(p[i].v,p[i+1].v); 73 }else break; 74 } 75 long long ans = 0; 76 long long value[26]; 77 for(int i=0;i<26;i++){ 78 value[p[i].w]=p[i].v; 79 } 80 for(int i=0;i<n;i++){ 81 long long now = 1; 82 for(int j=0;j<s[i].size();j++){ 83 ans=(ans+(value[s[i][j]-'a']*now)%mod)%mod; 84 now=(now*26)%mod; 85 } 86 } 87 cout<<"Case #"<<cas<<": "<<ans<<endl; 88 } 89 }