2017 Multi-University Training Contest 2.Balala Power!(贪心)

链接:http://acm.hdu.edu.cn/showproblem.php?pid=6034

分析:做了半天才发现贪心得不对。。先处理出每一位出现的字符各有多少个,然后对超过26个的进位一下!!!类似桶排的做法从大到小排序一下就可以了,注意如果最小的出现在前导位置上,往前推到非前导的为止,然后把经过的全部+1,把非前导的那个当0。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 using namespace std;
 6 typedef long long ll;
 7 const int mod=1e9+7,maxn=1e5+5;
 8 int n;
 9 char s[maxn];
10 ll coun[maxn][26];
11 ll to[26];
12 ll r[26];
13 long long ans=0;
14 int len=0,idx;
15 bool Is_same[maxn],Is_start[26];
16 bool Cmp(ll a,ll b){
17     return coun[idx][a]>coun[idx][b];
18 }
19 void solve(){
20     for(int i=0;i<26;i++)Is_same[i]=true;
21     for(int j=0;j<26;j++){
22         int c=0;
23         for(int i=maxn-1;i>=maxn-len;i--){
24             if(coun[i][j]>=26){
25                 if(i==maxn-len)len++;
26                 coun[i-1][j]+=coun[i][j]/26;
27                 coun[i][j]%=26;
28 
29             }
30         }
31     }
32     ans=0;
33     int s=0,t=0;
34     idx=maxn-len;
35     sort(r,r+26,Cmp);
36     for(int i=maxn-len+1;i<maxn;i++){
37         s=0;
38         while(s<25){
39             t=s;
40             while(t<25&&Is_same[t]&&coun[i-1][r[t]]==coun[i-1][r[t+1]])
41                 t++;
42             if(s!=t){
43                 idx=i;
44                 sort(r+s,r+t+1,Cmp);
45             }
46             Is_same[t]=false;
47             s=t+1;
48         }
49     }
50     if(Is_start[r[25]]){
51         int i=24;
52         while(Is_start[r[i]])
53             i--;
54         int q=r[i];
55         for(int j=i+1;j<26;j++)
56             r[j-1]=r[j];
57         r[25]=q;
58     }
59     for(int i=0;i<26;i++){
60         to[r[i]]=25-i;
61     }
62     for(int i=maxn-len;i<maxn;i++){
63         ans=(ans*26)%mod;
64         for(int j=0;j<26;j++){
65             ans=(ans+coun[i][j]*to[j])%mod;
66         }
67     }
68 }
69 int main(){
70     //freopen("e:\\in.txt","r",stdin);
71     int kase=0;
72     while(scanf("%d",&n)!=EOF){
73         len=0;
74         memset(coun,0,sizeof(coun));
75         memset(Is_start,0,sizeof(Is_start));
76         memset(to,-1,sizeof(to));
77         for(int i=0;i<26;i++)
78             r[i]=i;
79         for(int i=0;i<n;i++){
80             scanf("%s",s);
81             int l=strlen(s);
82             len=max(len,l);
83             if(l>1)
84                 Is_start[s[0]-'a']=true;
85             for(int j=1;j<=l;j++){
86                 coun[maxn-j][s[l-j]-'a']++;
87             }
88         }
89         solve();
90         cout<<"Case #"<<++kase<<": "<<ans<<endl;
91     }
92     return 0;
93 }

 

posted @ 2017-07-25 22:41  7391_KID  阅读(191)  评论(0编辑  收藏  举报