HDU 6034 Power!

来源:互联网 发布:电视mac认证状态异常 编辑:程序博客网 时间:2024/06/02 04:29

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

题目意思

题目大意为:给你一个n,后面有n个字符串,字符串每个字母对应0到25之间的一个数,问你这些字母分别等于多少时候字符串代表的值总和最大(相当于25进制)。而且在字符串不能能有前导0出现。(数值过大对10^9+7取余)

解题思路

不考虑统计没个字符在权位谁高谁低,然后就从25排到0就好了,但是他又要求不能有前导0,所以就必须开个数组标记每个字符是否在大于2的字符串的首位出现,然后在没有出现的字母把权位最低的字母赋值给0,剩下的就又按25到1从到到低排就可以了。

代码部分

#include <iostream>#include <stdio.h>#include <cstring>#include <string>#include <algorithm>using namespace std;const long long int p=1e9+7;const int maxn=100005;long long int m[maxn]; //struct node{    int vis;    char a[maxn];   ///存每个字符在哪个位子出现的次数用int会出错,下面排序没法排}num[27];bool cmd(node a,node b){    for(int i=maxn-1;i>0;i--)    {        if(a.a[i]!=b.a[i])        {            return a.a[i]>b.a[i];        }    }    return a.a[0]>b.a[0];}void init()   ///打每位权重{    m[0]=1;    long long int ans=26;    for(int i=1;i<maxn;i++)    {        m[i]=ans;        ans=(ans*26)%p;    }}int main(){    int n,T=1; init();    while (scanf("%d",&n)!=EOF)        {        for(int i=0;i<26;i++)    ///初始化        {            num[i].vis=0;            for(int j=0;j<maxn;j++) num[i].a[j]=0;        }        for (int i=0;i<n;i++)        {            char c[maxn];            int l;            scanf("%s",&c);            l=strlen(c);            if (l!=1)     ///标记是否可以为0                num[c[0]-'a'].vis=1;            for(int j=0;j<l;j++)   ///统计没个位上字母出现的次数            {                int x=c[j]-'a';                int y=l-j-1;                num[x].a[y]++;                while(num[x].a[y]==26)   //26后要进1,必须用while防止不断进                {                    num[x].a[y++]=0;                    num[x].a[y]++;                }            }        }            sort(num,num+26,cmd);  //把权值高的排在前面            int t;            for (int i=25;i>=0;i--)  //从低的开始确认0该给哪个字母            {                if(num[i].vis==0)                {                    t=i;                    break;                }            }            long long int ans=0;            int k=25;            for (int i=0;i<=25;i++,k--)  //计算总和            {                if (i!=t)                    for(int j=0;j<maxn;j++)                {                    (ans+=(k*m[j]*num[i].a[j]))%=p;                }                else if(i==t)                    k++;            }            printf("Case #%d: %lld\n",T++,ans);    }}