打字(贪心)
Description
snow 是个热爱打字的家伙,每次敲出更快的速度都会让他很开心。现在,他拿到一篇新的打字文章,已知这篇文章只有 26 个小写英文字母,给出 snow 打出这 26 个英文字母分别需要多少时间 (s),问 snow 打完这篇文章获得的 kpm(打正确的字数/所花的分钟数)最大为多少?
注意 snow 可能会打错一些字哦。打错的必定是文章里面存在的。
Input
多组输入。
对于每组数据,首先输入 26 个整数,分别表示打出 a, b, c, ..., z 这 26 个字母需要的时间(保证是 int 范围内的正整数),然后给出一个字符串,长度不超过 1000,保证只包含小写英文字母。
Output
对于每组数据,输出一行,表示最大的 kpm,保留 2 位小数。
Sample Input
1 2 2 1 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 abcd 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 abcd
Sample Output
40.00 25.71
解题思路:我们会发现要求最终的结果是一个比值kpm(打正确的字数/所花的分钟数),我们可以通过敲错字母来改变所花费的时间,但同样也要注意正确的打字数也会改变。这里我们的贪心策略是使用文章
中时间最短的字母来代替一个时间比较长的字母然后敲错。一开始需要按照打每个字母所花时间从小到大给每个字母排序,找出花费时间最少的那个字母,用这个字母逐渐去替换耗费时间长的字母,记录比值
kpm,知道找到最大的kpm。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 #define INF 0x3f3f3f3f 6 int a[30]; 7 char s[10010]; 8 int num[10010]; 9 int my_comp(int a,int b) 10 { 11 return a<b; 12 } 13 int main() 14 { 15 int i,len,minn; 16 double ans,sum; 17 while(scanf("%d",&a[0])!=EOF) 18 { 19 for(i=1;i<26;i++) 20 { 21 scanf("%d",&a[i]);///每个字母的权重 22 } 23 getchar(); 24 scanf("%s",s); 25 len=strlen(s); 26 minn=INF; 27 for(i=0;i<len;i++) 28 { 29 num[i]=a[s[i]-'a']; 30 minn=min(minn,num[i]);///打字耗时最短的字母 31 } 32 sort(num,num+len,my_comp);///按照每个字母的权重从小到大排序 33 ans=0.0; 34 sum=0.0;///所花费的时间 35 for(i=0;i<len;i++) 36 { 37 sum=sum+num[i];///从小到大存储到sum中 38 ans=max(ans,double(i+1)/(sum+double(len-i-1)*minn));///使用最小耗时的字母逐渐替换耗时大的字母,直到找出最大的比值 39 } 40 printf("%.2lf\n",ans*60.0); 41 } 42 return 0; 43 }