算法习题——美丽的字符串

摘自Facebook杯2013年编程挑战赛预选赛,链接(http://www.cnblogs.com/newyorker/archive/2013/01/31/2886278.html)觉得题目挺有意思,就自己用C++实现了一下

问题描述:
对于一个字符串,定义这个字符串的“美丽程度”是其所有字母“美丽程度”的总和(sum)。
每个字母都有一个“美丽程度”,范围在1到26之间。没有任何两个字母拥有相同的“美丽程度”。字母忽略大小写。
给出一个字符串,计算它最大可能的“美丽程度”。

官方答案:
这是本轮比赛最简单的题目。一共有10697名参赛者尝试解决此题,其中9865名参赛者成功解决。解法的核心思想是:计算每个字母出现的频率,给频率最多的字母赋予“美丽程度值”26,以此类推。如果两个字母频率相等,可以任意挑一个赋予稍高的值,因为不影响字符串总和。

个人分析:
首先需要统计字符的出现频率,存储在一个map里。然后遍历这个map,按照出现频率从高到低的顺序。把26-1的“美丽程度值”乘以字符的出现次数,最后求和即是整个字符串的“美丽值”。
在创建map的时候,默认是按照键(这里是一个char型)来排序的。但在这个问题里我们需要使用值的降序。先对map进行按值排序也是可以的。但因为map的长度只有26,不如就直接暴力遍历了。

 1 #include<string>
 2 #include<map>
 3 #include<iostream>
 4 using namespace std;
 5 
 6 int main(){
 7     string src;
 8     typedef map<char,int> CharMap;
 9     typedef map<char,int>::iterator iterator;
10     CharMap countMap;
11     cin>>src;
12 
13     for(int i=0;i<src.length();i++){
14         if(countMap.find(src[i])!=countMap.end()){
15             countMap[src[i]]++;
16         }
17         else
18             countMap[src[i]]=1;
19     }
20 
21     int beautyCount=0;
22     int curBeauty=26;
23     while(!countMap.empty()){
24         int curMax=0;
25         char maxPos=0;
26         iterator it=countMap.begin();
27         for(;it!=countMap.end();it++){
28             if( it->second > curMax ){
29                 curMax=it->second;
30                 maxPos=it->first;
31             }
32         }
33         if(curMax>0){
34             countMap.erase(countMap.find(maxPos));
35             cout<<maxPos<<' '<<curMax<<endl;
36             beautyCount+=(curMax*curBeauty--);
37         }
38     }
39     cout<<beautyCount<<endl;
40     
41     return;
42 }

 

posted @ 2013-05-15 11:54  现代魔法入门  阅读(1140)  评论(0)    收藏  举报