CF 910 C. Minimum Sum

链接

[http://codeforces.com/group/1EzrFFyOc0/contest/910/problem/C]

题意

给你n个字符串,每个字符串的字符是aj,每个字符都可以是09的替换,不能有前导零
问你怎么替换使得所有个字符串的总和最小

分析

统计每个字符出现的次数,比如abc,a出现了100次,b出现了10次,c出现了1次。同时标记是否出现在首位置
后面先排序出现的次数,但注意用选择排序时标记也跟着换,最后贪心就好了,具体看代码

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll pow(ll x,ll y){//快速幂 
	ll ans=1;
	ll base=x;
	while(y){
		if(y&1) ans*=base;
		base*=base;
		y>>=1;
	}
	return ans;
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	//freopen("in.txt","r",stdin);
	ll n,i,j;
	string s;
	ll b[12];//标记某字符是否出现在首位置 
	ll cnt[12];
	while(cin>>n){
		memset(cnt,0,sizeof(cnt));
		memset(b,0,sizeof(b));
		for(i=0;i<n;i++){
			cin>>s;
			ll len=s.length();
		   	b[s[0]-'a']=1;
		   	for(j=len-1;j>=0;j--)
		   	cnt[s[j]-'a']+=pow(10,len-1-j);//统计每个字符出现的次数 
		}
		
		for(i=0;i<9;i++){//选择排序,因为要对是否出现在首位置,也要同时换位,为了避免有前导零 
			for(j=i+1;j<10;j++){
				if(cnt[j]>cnt[i]){
					ll h;
					h=cnt[i];cnt[i]=cnt[j];cnt[j]=h;
					h=b[i];b[i]=b[j];b[j]=h;
				}
			}
		}
		ll sum=0;
		bool flag=1;//用于标记0是否被使用过 
	  for(i=0;i<10;i++)
	  	if(flag){
	  		if(b[i])
	  			sum+=(i+1)*cnt[i];
			  else
			  	flag=0;
		  }
		  else
		  	sum+=i*cnt[i];

	  cout<<sum<<endl;
	}
	return 0;
}
posted @ 2018-10-05 13:26  ChunhaoMo  阅读(198)  评论(0)    收藏  举报