HDU 6034 Balala Power!(贪心+排序)

Balala Power!

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1411    Accepted Submission(s): 239

Problem Description

Talented Mr.Tang has n strings consisting of only lower case characters. He wants to charge them with Balala Power (he could change each character ranged from a to z into each number ranged from 0 to 25, but each two different characters should not be changed into the same number) so that he could calculate the sum of these strings as integers in base 26 hilariously.

Mr.Tang wants you to maximize the summation. Notice that no string in this problem could have leading zeros except for string "0". It is guaranteed that at least one character does not appear at the beginning of any string.

The summation may be quite large, so you should output it in modulo 109+7.
 
Input
The input contains multiple test cases.

For each test case, the first line contains one positive integers n, the number of strings. (1n100000)

Each of the next n lines contains a string si consisting of only lower case letters. (1|si|100000,|si|106)
 
Output
For each test case, output "Case #x: y" in one line (without quotes), where x indicates the case number starting from 1 and y denotes the answer of corresponding case.
 
Sample Input
1
a
2
aa
bb
3
a
ba
abc
 
Sample Output
Case #1: 25
Case #2: 1323
Case #3: 18221

题目链接:HDU 6034

嗯今天多校第一场的一道题由于不知道怎么地把cmp函数写炸了,最后就没写出来。很显然肯定是把最大的系数留给贡献最大的字母,因此贪心地把最大的系数从25-0依次赋值,然后再选取一个最小贡献且不是开头字母的来牺牲一下获得系数0,其他的字母就均不为0了。然后预处理一下26的指数即可,贡献怎么算?一开始按对贡献取模之后排序,后来发现取模之后的排肯定不对,然后用一个结构体记录每一个字母和它出现的位数以及次数,然后手动模拟进位一下,否则比如第0位出现100次肯定比第1位出现1次贡献大(此处要注意可能会进位到maxlen处,比较的时候要多一位,否则WA),最后写一个比较奇怪的cmp函数就可以了,这样就可以正常地排序比较。

代码:

#include <stdio.h>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <bitset>
#include <string>
#include <stack>
#include <cmath>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
#define fin(name) freopen(name,"r",stdin)
#define fout(name) freopen(name,"w",stdout)
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
typedef pair<int, int> pii;
typedef long long LL;
const double PI = acos(-1.0);
const int N = 1e5 + 7;
const LL mod = 1e9 + 7;
LL fac[N];
char s[N];
int ishead[30], maxlen;

struct info
{
    char c;
    LL val;
    int f[N];
    void init()
    {
        val = 0LL;
        CLR(f, 0);
    }
    void cal()
    {
        for (int i = 0; i < maxlen; ++i)
        {
            if (f[i] >= 26)
            {
                f[i + 1] += f[i] / 26;
                f[i] %= 26;
            }
        }
    }
    bool operator<(const info &rhs)const
    {
        for (int i = maxlen; i >= 0; --i)
        {
            if (f[i] != rhs.f[i])
                return f[i] < rhs.f[i];
        }
    }
};
info arr[26];

void init()
{
    CLR(ishead, 0);
    maxlen = 0;
    for (int i = 0; i < 26; ++i)
        arr[i].init();
}
int main(void)
{
    int i, j, n;
    fac[0] = 1LL;
    for (i = 1; i < N; ++i)
        fac[i] = fac[i - 1] * 26LL % mod;
    int q = 1;
    while (~scanf("%d", &n))
    {
        init();
        for (i = 0; i < n; ++i)
        {
            scanf("%s", s);
            int len = strlen(s);
            if (len > 1)
                ishead[s[0] - 'a'] = 1;
            if (len > maxlen)
                maxlen = len;
            for (j = 0; j < len; ++j)
            {
                int id = s[j] - 'a';
                arr[id].val = (arr[id].val + fac[len - j - 1]) % mod;
                ++arr[id].f[len - j - 1];
            }
        }
        for (i = 0; i < 26; ++i)
        {
            arr[i].c = 'a' + i;
            arr[i].cal();
        }
        int sw = 0;
        for (i = 0; i < 26; ++i)
        {
            if (!ishead[arr[i].c - 'a'] && arr[i] < arr[sw])
                sw = i;
        }
        swap(arr[0], arr[sw]);
        sort(arr + 1, arr + 26);
        LL ans = 0;
        for (i = 0; i < 26; ++i)
        {
            ans = ans + (arr[i].val * (LL)(i)) % mod;
            ans %= mod;
        }
        printf("Case #%d: %I64d
", q++, ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Blackops/p/7236709.html