感觉自己代码能力真是差的一逼.
本题题意为,认为每一个字母都是一个26进制的数(一一对应),于是每一个字符串也就成了一个数字
例如 abc, 假设对应关系a->25 b->23 c->22 则代表26进制数字 252322.
而题意就是要你求出进行转换之后,所有字符串的最大和(十进制).
当然思路就是如何建立对应关系使其最大,考虑到一个字母在一个位置上,意味着他的对应值乘以该数位的权值,所以我们可以如此计算每个字母的权重.
例如 abc
ba
a
我们有 a 102 b 20 c 1,当然要考虑进位.
故为 a>b>c a=25,b=24,c=23.
需注意的是处理前导零,选择最小的可以为0的为零,其他就可以原样排了.
看代码
/* xzppp*/
#include <iostream>
#include <vector>
#include <set>
#include <queue>
#include <map>
#include <algorithm>
#include <stdio.h>
#include <string.h>
using namespace std;
const int MAXN = 1e5;
const int INF = 0x7ffffff;
const int MOD = 1e9+7;
typedef long long LL;
struct dap{
int ng[MAXN+17],l,id,num;
bool cant;
}a[26];
bool cmp(dap &x,dap& y)
{
if(x.l==y.l) {
for(int i=x.l;i>0;i--) {
if(x.ng[i]!=y.ng[i]) {
return x.ng[i]<y.ng[i];
}
}
}
else
return x.l<y.l;
}
LL st[MAXN+17];
int main(){
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,ml=0,t=1;
st[0]=1;
for (int i = 1; i < MAXN+17; ++i){
st[i]=st[i-1]*26;
st[i]=st[i]%MOD;
}
while(cin>>n){
for (int i = 0; i < 26; ++i){
a[i].id = i;
for (int j = 0; j < MAXN+17; ++j) a[i].ng[j]=0;
a[i].l = 0;
a[i].cant = false;
a[i].num = -1;
}
for (int i = 0; i < n; ++i) {
char b[MAXN+17];
scanf("%s",b);
int lth = strlen(b);
ml = max(lth, ml);
for (int j = 0; j < lth; ++j)
(a[b[j]-'a'].ng[lth-1-j])++;
a[b[0]-'a'].cant = true;
}
for (int i = 0; i < 26; ++i)
for (int j = 0; j < ml+17 ; ++j){
if(a[i].ng[j]>0)
a[i].l = max(a[i].l, j+1);
int temp = a[i].ng[j]/26;
a[i].ng[j]-=26*temp;
a[i].ng[j+1]+=temp;
}
sort(a,a+26,cmp);
for (int i = 0; i < 26; ++i)
if(!a[i].cant)
{
a[i].num = 0;
break;
}
int temp = 25,cal[26],ans = 0;
for (int i = 25; i > -1 ; --i)
{
if(a[i].num!=-1) continue;
a[i].num = temp;
temp--;
}
for (int i = 0; i < 26; ++i)
cal[a[i].id] = a[i].num;
for (int i = 0; i < 26; ++i)
for (int j = 0; j < MAXN+17; ++j) {
int temp = (cal[a[i].id]*a[i].ng[j]*st[j])%MOD;
ans = (ans+temp)%MOD;
}
printf("Case #%d: %d\n",t++,ans);
}
return 0;
}