HDU 6034

/*
HDU 6034 - Balala Power!  [  大数进位,贪心 ]
题意:
	给一组字符串(小写英文字母),将上面的字符串考虑成26进制数,每个字母分配一个权值,问这组数字加起来的和最大是多少?
	要求每个数字不能有前导0,即每个字符串首位字符不能赋0
分析:
	对于每个字符,将每个字符串按位相加,得到这个字符的一个每位上的数量的数组
	将其看成一个大数,满26进位,然后排序,从高到低赋值,注意考虑0
*/
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const LL MOD = 1000000007;
LL mp[150005][26];
int n, m;
char s[100005];
bool notz[26];
int val[26], a[26];
void up()
{
    for (int j = 0; j < 26; j++)
    {
        for (int i = 0; i < m; i++) {
            mp[i+1][j] += mp[i][j] / 26;
            mp[i][j] %= 26;
        }
        while (mp[m][j]) {
            mp[m+1][j] += mp[m][j] / 26;
            mp[m][j] %= 26;
            m++;
        }
    }
}
bool cmp(int a, int b) {
	for (int i = m-1; i >= 0; i--) {
		if (mp[i][a] != mp[i][b]) return mp[i][a] > mp[i][b];
	}
	return 0;
}
void solve()
{
    for (int i = 0; i < 26; i++) a[i] = i;
    sort(a, a+26, cmp);
    for (int i = 25; i >= 0; i--)
    	if (!notz[a[i]]) {
    		val[a[i]] = 0; break;
		}
    int tmp = 25;
    for (int i = 0; i < 26; i++) 
    	if (val[a[i]] == -1) val[a[i]] = tmp--;	
}
int main()
{
    int tt = 0;
    while (~scanf("%d", &n))
    {
        memset(notz, 0, sizeof(notz));
        memset(mp, 0, sizeof(mp));
        memset(val, -1, sizeof(val));
        m = 0;
        for (int i = 1; i <= n; i++)
        {
            scanf("%s", s);
            int len = strlen(s);
            if (len != 1) notz[s[0]-'a'] = 1;
            m = max(m, len);
            for (int i = 0; i < len; i++) mp[len-i-1][s[i]-'a']++;
        }
        up();
        solve();
        LL ans = 0;
        for (int i = m-1; i >= 0; i--)
        {
            ans = ans * 26 % MOD;
            for (int j = 0; j < 26; j++)
            {
                ans = (ans + (LL)mp[i][j]*val[j] % MOD) % MOD;
            }
        }
        printf("Case #%d: %lld
", ++tt, ans % MOD);
    }
}

  

我自倾杯,君且随意
原文地址:https://www.cnblogs.com/nicetomeetu/p/7247339.html