【HDU6034】Balala Power!

来源:互联网 发布:凌波城静脉不动的算法 编辑:程序博客网 时间:2024/06/11 02:00

记录一个菜逼的成长。。

2017 Multi-University Training Contest - Team 1

题目链接
题目大意:
给你n个小写的字符串。
给每种小写字母赋值,每个字符串就相当于一个数,使得最后的和最大。

考虑每种字母的贡献,
如果一个字母贡献大,那么这个字母必然出现在高位且次数多。
根据这个规则排序
对次数考虑进位,可以使常数变小。
再考虑不能给出现过字符串头的字母赋值0

#include <bits/stdc++.h>using namespace std;#define rep(i,l,r) for( int i = l; i <= r; i++ )#define rep0(i,l,r) for( int i = l; i < r; i++ )#define ALL(v) (v).begin(),(v).end()#define cl(a,b) memset(a,b,sizeof(a))#define clr clear()#define pb push_back#define mp make_pair#define fi first#define se secondtypedef long long LL;typedef pair<int,int> PII;const int INF = 0x3f3f3f3f;const int MOD = 1e9+7;const int maxn = 100000 + 10;int cnt[27][maxn],head[27],a[27],mxlen;LL Power[maxn],sum[27];char str[maxn];bool cmp(int a,int b){  for( int i = mxlen-1; i >= 0; i-- ){    if(cnt[a][i] != cnt[b][i])      return cnt[a][i] < cnt[b][i];  }  return 0;}int main(){  Power[0] = 1;  for( int i = 1; i < maxn; i++ ){    Power[i] = Power[i-1] * 26 % MOD;  }  int n,cas = 1;  while(~scanf("%d",&n)){    cl(cnt,0);cl(sum,0);cl(head,0);    mxlen = 0;    for( int i = 1; i <= n; i++ ){      scanf("%s",str);      int len = strlen(str);      if(len > 1)head[str[0]-'a'] = 1;      mxlen = max(mxlen,len);      for( int j = len-1; j >= 0; j-- ){        cnt[str[j]-'a'][len-j-1] ++;        sum[str[j]-'a'] += Power[len-j-1];//预处理假设所有字母值为1,最后只要乘上给每种字母的权值即可        if(sum[str[j]-'a'] >= MOD)sum[str[j]-'a'] -= MOD;      }    }    //对次数进位,减小常数    for( int i = 0; i < 26; i++ ){      for( int j = 0; j < mxlen; j++ ){        cnt[i][j+1] += cnt[i][j] / 26;        cnt[i][j] %= 26;      }      while(cnt[i][mxlen]){        cnt[i][mxlen+1] += cnt[i][mxlen] / 26;        cnt[i][mxlen++] %= 26;      }      a[i] = i;    }    sort(a,a+26,cmp);    int zero = -1;    //在字符串头部出现过的字母不能赋值0,从小往大遍历,找到可以赋值0,且贡献最小的字母    for( int i = 0; i < 26; i++ )      if(!head[a[i]]){zero = a[i];break;}    LL ans = 0;    for( int x = 25,i = 25; i >= 0; i-- ){      if(a[i] != zero){        ans = (ans + (LL)x-- * sum[a[i]]) % MOD;      }    }    printf("Case #%d: %lld\n",cas++,ans);  }  return 0;}
原创粉丝点击