HDU6034 Balala Power! [贪心]

本文介绍了一种处理特定字符串问题的算法解决方案。通过计算每个字符的重要性,并使用贪心策略进行排序和赋值,最终得出字符串的有效评估值。

题意:给n个字符串,每个字符串只包括'a'~'z',可以给每个小写字母赋0~25的值,不同字母要求不一样的值。(注意不可以有前导0)

题解:首先肯定是要对每个字母按权值(用26进制)记录它的重要性,然后对每个字母的权值排序,之后以为需要用到km(=。=),一直不明re,后来发现只要贪心按权值从小到大去的去找符合条件的去赋值为0,其余按权值从大到小一次赋值(一开始快排炸了不知道为什么,改成了冒泡)。

AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll mod=(ll)(1e9+7);
char s[111111];
ll ma,n;
struct node{
    ll sum[111111];
    char c;
    int id;
}a[30];
ll ans[30];
ll mark[30];
bool cmp(node b,node c){    
    for(ll i=ma-1;i>=0;i--){    
        if(b.sum[i]==c.sum[i]) continue;
        else return b.sum[i]>c.sum[i];
    }
    return true;
}
int chuxian[30];
int main(){
    ll cas=1;
    while(scanf("%lld",&n)!=EOF)
	{
        for(ll i=0;i<30;i++)    memset(a[i].sum,0,sizeof(a[i].sum));
        memset(mark,0,sizeof(mark));
        memset(ans,0,sizeof(ans));
        ma=0;
        for(ll i=1;i<=n;i++){
            scanf("%s",s);
            ll l=strlen(s);
            ll tot=0;
            mark[s[0]-'a']=1;
            for(ll j=l-1;j>=0;j--){
                a[s[j]-'a'].sum[tot++]+=1;
                chuxian[s[j]-'a']=1;
            }
            ma=max(ma,tot);
        }
        for(ll i=0;i<=25;i++){
            for(ll j=0;j<ma-1;j++){
                ll x=a[i].sum[j]/26;
                a[i].sum[j]%=26;
                a[i].sum[j+1]+=x;

            }
            a[i].c='a'+i;
            a[i].id=i;
        }
        for(ll ii=0;ii<=24;ii++){
            for(ll jj=ii+1;jj<=25;jj++){
                ll ok=1;
                int i=a[ii].id;
                int j=a[jj].id;
                for(ll k=ma-1;k>=0;k--){    
                    
                    if(a[i].sum[k]==a[j].sum[k]) continue;
                    else if(a[i].sum[k]<a[j].sum[k]){
                        ok=1;
                    }
                    else if(a[i].sum[k]>a[j].sum[k]){
                        ok=0;
                        
                    }
                    break;
                }
                if(ok==1) swap(a[ii].id,a[jj].id);
            }
        }
        int pos;
        int ttt=25;
        for(int i=25;i>=0;i--){
            int bh=a[i].id;
            if(mark[a[bh].c-'a']==0){
                ans[a[bh].c-'a']=0;
                pos=i;
                break;
            }
        }
        for(int i=0;i<=25;i++){
            if(pos==i) continue;
            int bh=a[i].id;
            ans[a[bh].c-'a']=ttt--;
        }
        ll ss=0;
        for(ll i=0;i<=25;i++){
            ll tt=1;
            int bh=a[i].id;
            for(ll j=0;j<ma;j++){
                ss=(ss+(a[bh].sum[j]*tt%mod)*ans[a[bh].c-'a']%mod)%mod;
                tt=(tt*26)%mod;
            }
        }
        printf("Case #%lld: %lld\n",cas++,ss%mod);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值