HDU6034Balala Power!(大数进制转换)

来源:互联网 发布:洞主手工皂淘宝在哪 编辑:程序博客网 时间:2024/06/16 23:07
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;/*大数进制转换给定n个字符串,如何给a-z赋值,使得给定字符串在26进制下的和最大如果字符串超过两位,最高位不能为0*/typedef long long LL;const int mod=1e9+7;const int maxn=1e5+100;int n;int cnt[27][maxn];char s[maxn];bool vis[27];int p[27];int dig;//对每个字母的值进行排序,排序对象为字母IDbool cmp(int a,int b){    for(int j=dig; j>=0; j--)//大数的比较    {        if(cnt[a][j]!=cnt[b][j])        {            return cnt[a][j]<cnt[b][j];        }    }    return a<b;}LL solve(){    for(int i=0; i<26; i++)//26进制大数加法    {        p[i]=i;        for(int j=0; j<dig; j++)        {            cnt[i][j+1]+=cnt[i][j]/26;            cnt[i][j]=cnt[i][j]%26;        }    }    sort(p,p+26,cmp);    int pos=-1;//一定会存在一个字母可以取0    for(int i=0; i<26; i++)    {        if(vis[p[i]]==0)//寻找值最小,又可以取0的字母        {            pos=i;            break;        }    }    for(int i=pos; i>=1; i--)//将该字母移到最左边    {        swap(p[i],p[i-1]);    }    LL ans=0;    LL k=1;    for(int i=0; i<26; i++)//i为该字母表示的数字    {        k=1;        for(int j=0; j<=dig; j++)        {            ans=(ans+cnt[p[i]][j]*k%mod*i%mod)%mod;            k=k*26%mod;//该位相应的权值        }    }    return ans;}int main(){    int kase=1;    while(~scanf("%d",&n))    {        memset(cnt,0,sizeof(cnt));        memset(vis,0,sizeof(vis));        memset(p,0,sizeof(p));        dig=-1;        for(int i=0; i<n; i++)        {            scanf("%s",s);            int len=strlen(s);            reverse(s,s+len);//逆置字符串            for(int j=0; j<len; j++)            {                int c=s[j]-'a';                cnt[c][j]++;//分别统计每个位置,不同字母数量            }            dig=max(dig,len);//保存最大高位            vis[s[len-1]-'a']=1;//标记在最高位出现过的字母        }        printf("Case #%d: %I64d\n",kase++,solve());    }}