[HDOJ6034] Balala Power!(模拟,贪心,大数)

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

题意:给'a'到'z'重新安排顺序,使得在给出的n个字符串分别代表的26进制数和最大。

一开始'a'到'z'只起到占位作用,分别统计某个字符在某个位置出现的次数和这个位置代表的价值。之后对每个字符某个位置的和进行进位处理。按照每个26进制数的大小排序就行了。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 const LL mod = 1e9+7;
 6 const int maxn = 100100;
 7 char str[maxn];
 8 int n, sz;
 9 LL w[maxn], cnt[maxn][26], tot[26];
10 bool vis[26];
11 int perm[26];
12 
13 bool cmp(int i, int j) {
14     for(int k = sz - 1; k >= 0; k--) {
15         if(cnt[k][i] != cnt[k][j]) {
16             return cnt[k][i] < cnt[k][j];
17         }
18     }
19     return 0;
20 }
21 
22 signed main() {
23     // freopen("in", "r", stdin);
24     int _ = 1, len;
25     w[0] = 1;
26     for(int i = 1; i < maxn; i++) w[i] = w[i-1] * 26LL % mod;
27     while(~scanf("%d", &n)) {
28         sz = 0;
29         for(int i = 0; i < 26; i++) perm[i] = i;
30         memset(vis, 0, sizeof(vis));
31         memset(cnt, 0, sizeof(cnt));
32         memset(tot, 0, sizeof(tot));
33         for(int i = 0; i < n; i++) {
34             scanf("%s", str);
35             len = strlen(str);
36             if(len != 1) vis[str[0]-'a'] = 1;
37             sz = max(sz, len);
38             reverse(str, str+len);
39             for(int j = 0; j < len; j++) {
40                 cnt[j][str[j]-'a']++;
41                 tot[str[j]-'a'] += w[j];
42                 tot[str[j]-'a'] %= mod;
43             }
44         }
45         for(int i = 0; i < 26; i++) {
46             for(int j = 0; j < sz; j++) {
47                 cnt[j+1][i] += cnt[j][i] / 26;
48                 cnt[j][i] %= 26;
49             }
50             while(cnt[sz][i]) {
51                 cnt[sz+1][i] += cnt[sz][i] / 26;
52                 cnt[sz][i] %= 26;
53                 sz++;
54             }
55         }
56         sort(perm, perm+26, cmp);
57         int pos = -1;
58         for(int i = 0; i < 26; i++) {
59             if(!vis[perm[i]]) {
60                 pos = perm[i];
61                 break;
62             }
63         }
64         LL ret = 0;
65         int p =  25;
66         for(int i = 25; i >= 0; i--) {
67             if(pos == perm[i]) continue;
68             ret += (LL)p * tot[perm[i]] % mod;
69             ret %= mod; p--;
70         }
71         printf("Case #%d: %lld\n", _++, ret);
72     }
73     return 0;
74 }

 

posted @ 2017-08-21 21:57  Kirai  阅读(176)  评论(0编辑  收藏  举报