Balala Power!
题意:给n个字符串,让你给每一个小写字母赋一个值(0到25),使得所有的字符串的总和最大。
把每一个字符串看作一个26进制的数
先统计每个字母在不同位置出现的次数,然后按出现次数的多少排序,出现的多的自然赋大的值
注意题目要求不能有前导零,所以排序后拍到最后的那个字母如果在某个字符串首位出现过,就要和前面的换一下
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 const int mod=1e9+7; 5 const int maxn=1e5+10; 6 const int maxe=1e6+10; 7 int maxlen,n; 8 struct Node{ 9 int id; 10 int cnt[maxn]; 11 bool operator <(const Node &a)const{ 12 for(int i=maxlen;i>=0;i--) if(cnt[i]!=a.cnt[i]) return cnt[i]>a.cnt[i]; 13 return 0; 14 } 15 }p[33]; 16 ll base[maxn]; 17 char s[maxe]; 18 int st[maxn],ed[maxn]; 19 20 int vis[33]; 21 ll num[33]; 22 23 int main(){ 24 int kase=0; 25 base[0]=1; 26 for(int i=1;i<maxn;i++) base[i]=base[i-1]*26%mod; 27 maxlen=0; 28 while(scanf("%d",&n)!=EOF){ 29 for(int i=0;i<26;i++){ 30 vis[i]=0; 31 for(int j=0;j<=maxlen;j++) p[i].cnt[j]=0; 32 p[i].id=i; 33 } 34 int x=0; 35 for(int k=0;k<n;k++){ 36 scanf("%s",s+x); 37 int len=strlen(s+x); 38 st[k]=x; 39 x+=len; 40 ed[k]=x; 41 for(int i=ed[k]-1,j=0;i>=st[k];i--,j++){ 42 if(i==st[k]) vis[s[i]-‘a‘]=1; 43 int c=s[i]-‘a‘; 44 p[c].cnt[j]++; 45 } 46 } 47 maxlen=0; 48 for(int i=0;i<26;i++){ 49 for(int j=0;j<maxn-1;j++){ 50 p[i].cnt[j+1]+=p[i].cnt[j]/26; 51 p[i].cnt[j]%=26; 52 if(p[i].cnt[j]>0) maxlen=max(maxlen,j); 53 } 54 } 55 sort(p,p+26); 56 if(vis[p[25].id]){ 57 int i; 58 for(i=25;i>=0;i--) if(vis[p[i].id]==0) break; 59 p[26]=p[i]; 60 for(;i<26;i++) p[i]=p[i+1]; 61 } 62 for(int i=0;i<26;i++) num[p[i].id]=25-i; 63 ll ans=0; 64 for(int i=0;i<n;i++){ 65 int len=ed[i]-st[i]; 66 for(int j=0;j<len;j++){ 67 ans=(ans+num[s[j+st[i]]-‘a‘]*base[len-j-1]%mod)%mod; 68 } 69 70 } 71 printf("Case #%d: %lld\n",++kase,ans); 72 } 73 }
时间: 2024-12-20 17:38:54