HDU 6034 贪心 Balala Power!
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 3757 Accepted Submission(s): 907
Problem Description
Talented Mr.Tang has 7.
Input
The input contains multiple test cases.
For each test case, the first line contains one positive integers )
For each test case, the first line contains one positive integers )
Output
For each test case, output "Case #y denotes the answer of corresponding case.
Sample Input
1
a
2
aa
bb
3
a
ba
abc
Sample Output
Case #1: 25
Case #2: 1323
Case #3: 18221
Source
题意:
a~z每个字符代表着0~25中的个一个数字,因此一个字符串就可以表示成一个26进制的数字,给出n个字符串求这n个字符串和的最大值。
输入n
输入n行字符串
代码:
//进位和去前导零!!!;统计每个字符在某一位置出现的次数(共1e5个位置),然后贪心一定是贡献值最大的 //用25,把统计出来的数组按照高位出现次数大的排序(可以按照数组排序),然后算就行了。 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; const ll mod=1e9+7; const int maxl=100009; int pre[30]; ll f[maxl]; struct Lu{ int id,ss[maxl]; ll v; bool operator < (const Lu &p)const{ for(int i=maxl-3;i>=0;i--){ if(ss[i]>p.ss[i]) return 1; else if(ss[i]<p.ss[i]) return 0; } } }L[30]; void init(){ f[0]=1; for(int i=1;i<maxl;i++){ f[i]=f[i-1]*26%mod; } } int main() { init(); int cas=0,n; char str[maxl]; while(scanf("%d",&n)==1){ memset(pre,0,sizeof(pre)); memset(L,0,sizeof(L)); for(int i=0;i<n;i++){ scanf("%s",str); int len=strlen(str)-1; if(len!=0) pre[str[0]-'a']=1; for(int j=len;j>=0;j--){ int id=str[j]-'a'; L[id].ss[len-j]++; } } for(int i=0;i<26;i++){ L[i].id=i; for(int j=0;j<maxl-3;j++){ if(L[i].ss[j]>=26){ L[i].ss[j+1]+=L[i].ss[j]/26; L[i].ss[j]%=26; } } } sort(L,L+26); for(int i=0;i<26;i++) L[i].v=25-i; if(pre[L[25].id]){ //去前导零时可不是直接交换 for(int i=24;i>=0;i--){ if(!pre[L[i].id]){ for(int j=25;j>i;j--) L[j].v=L[j-1].v; L[i].v=0; break; } } } ll sum=0; for(int i=0;i<26;i++){ for(int j=maxl-3;j>=0;j--){ sum+=L[i].v*f[j]*L[i].ss[j]%mod; sum%=mod; } } printf("Case #%d: %lld ",++cas,sum); } return 0; }