hdu 6034

来源:互联网 发布:centos开启ssh端口 编辑:程序博客网 时间:2024/06/10 18:04

只能说这一题有点坑,需要细心,我错在一个自己以为对的地方wa了44发。

题意:给一个n,输入n个由小写之母组成的串,每个字母可以且只能对应0 -->25中的一个值。组成的数是26进制,问你怎样对应值才能得到最大的10进制,且输出值。

题目中提醒了前导不能为0。这是一个比较明显的坑。

我们可以先求出字符x,在m位出现了多少次,若>= 26次,则进位。从最高位开始,对字符出现的次数进行排队。比如1000 是大于999的,位数越高才越大。接下来,需要考虑0的情况。若字符m为前导,那么它不能为0,若它是最小值需要找到最小的不为前导的数n,然后值依次右移(本题中)。这是一个较隐蔽的坑,我就是这里一直wa,以为右移绝对正确,其实是n找错了。

/*ID: DickensToneLANG: C++PROB: palsquare*/#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;const int mod = 1e9 + 7;const int maxn = 100000 + 7;int num[30][maxn];bool vis[30];int val[30];int id[30];int maxl = 0;bool have[28];bool cmp(int x, int y){    for(int i = maxl; i >= 0; i--)    {        if(num[x][i] != num[y][i]) return num[x][i] > num[y][i];    }    return false;}void print(){    for(int i = 0; i <= 25; i++)        printf("%d %d\n", id[i], num[id[i]][0]);    printf("--------------------\n");    for(int i = 0; i <= 25; i++)        printf("%d %d\n", val[id[i]], id[i]);}int main(){    int kase = 1;    int n;    long long k[maxn];    k[0] = 1;    for(int i = 1; i < maxn; i++)        k[i] = (k[i - 1] * 26) % mod;    while(scanf("%d", &n) == 1)    {        maxl = 0;        memset(vis, 0, sizeof(vis));        memset(have, 0, sizeof(have));        memset(num, 0, sizeof(num));        char str[maxn];        for(int i = 0; i <= 26; i++)            id[i] = i;        for(int i = 0; i < n; i++)        {            scanf("%s", str);            int len = strlen(str);            if(len > 1) vis[str[0] - 'a'] = 1;            for(int l = len - 1; l >= 0; l--)            {                //printf("yes\n");                int p = len - 1 - l;                num[str[l] - 'a'][p] += 1;                have[str[l] - 'a'] = 1;                while(num[str[l] - 'a'][p] == 26)                {                    num[str[l] - 'a'][p++] = 0;                    num[str[l] - 'a'][p] += 1;                }                maxl = max(maxl, p);            }        }        //printf("%d\n", vis[25]);        //printf("%d\n", id[2]);        sort(id, id + 26, cmp);        int init = 25;        for(int i = 0; i <= 25; i++)        {            val[id[i]] = init--;            //printf("%d %d\n", id[i], init + 1);        }        if(vis[id[25]] == 1)        {            //printf("yes\n");            int t = 1;            while(vis[id[25 - t]])            {                t++;                //printf("%d\n", t);            }            for(int i = 25; i > 25 - t; i--)                val[id[i]] = val[id[i - 1]];            val[id[25 - t]] = 0;        }        //print();        //printf("%d\n", id[2]);        long long ans = 0;        for(int i = 0; i <= 25; i++)        {            if(!have[i]) continue;            //printf("%d\n", n);            for(int j = 0; j <= maxl; j++)            {                if(num[i][j])                    ans = (ans + (val[i] * k[j] * num[i][j]) % mod) % mod;            }            //printf("%lld\n", ans);        }        printf("Case #%d: %lld\n", kase++, ans);    }    return 0;}