2017 Multi-University Training Contest - Team 1 1002 Balala Power!

题目链接

题意
给定多个字符串,给二十六个字母赋予0~25的值,每个字符串形成一个26进制的数字,求怎么分配权值使得这几个字符串的和最大。

思路
官方:每个字符对答案的贡献都可以看作一个 26 进制的数字,问题相当于要给这些贡献加一个 0 到 25 的权重使得答案最大。最大的数匹配 25,次大的数匹配 24,依次类推。排序后这样依次贪心即可,唯一注意的是不能出现前导 0。
建一个26进制的数组num[26][100010]分别表示每一位的每一个字母有多少个,当超过26时向前进一位,然后进行排序,进行赋值。排序是先开一个26的数组表示每个字母所代表数字的顺序
代码(参考标程)

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;

const int INF = 0x3f3f3f3f;
const int MOD = 1e9+7;
const int MAXN = 100015;

int n, L;
int Case = 1;
int num[26][MAXN];
int power[MAXN], s[MAXN];
bool b[26];
char str[MAXN];
int a[26];

bool cmp (int A, int B)
{
    for (int i=L-1; i>=0; --i)
    {
         if (num[A][i] != num[B][i])
         {
             return num[A][i] < num[B][i];
         }
    }
}

void solve ()
{
    memset (num, 0, sizeof (num));
    memset (b, 0, sizeof (b));
    memset (s, 0, sizeof (s));
    L = 0;
    for (int i=0; iscanf ("%s", str);
        int len = strlen (str);
        if (len > 1)
            b[str[0] - 'a'] = 1;
        reverse (str, str + len);
        for (int j=0; j'a'][j] ++;
            s [str[j] - 'a'] += power[j];
            if (s[str[j] - 'a'] >= MOD)
                s [str[j] - 'a'] %= MOD;
        }
        L = max (L, len);
    }
    for (int i=0; i<26; ++i)
    {
        for (int j = 0; j < L; ++ j)
        {
            num [i][j+1] += num[i][j] / 26;
            num[i][j] %= 26;
        }
        while (num[i][L])
        {
            num[i][L+1] += num[i][L] / 26;
            num[i][L++] %= 26;
        }
        a[i] = i;
    }
    sort (a, a+26, cmp);
    int zero = -1;
    for (int i=0; i<26; ++i)
    {
        if (!b[a[i]])
        {
            zero = a[i];
            break;
        }
    }
    int res = 0, x = 25;
    for (int i=25; i>=0; --i)
    {
        if (a[i] != zero)
        {
            res += (ll) (x--) * s [a[i]] % MOD;
            res %= MOD;
        }
    }
     printf("Case #%d: %d\n" ,Case++ , res);
}
int main ()
{
    power [0] = 1;
    for (int i=1; i1] * 26 % MOD;
    while (~scanf ("%d", &n))
    {
        solve();
    }

    return 0;
}

你可能感兴趣的:(HDU,2017多校联合)