您的位置:首页 > 运维架构

Topcoder Open 2014 Algorithm Round 1A

2014-04-13 15:14 447 查看
250pt:

题意:给定一个变换规则:对一个长度为字符串S,任意选定一个序号i (0<= i <= length(S) - L),可对该字符串进行以下变换:

①保留前i个字符

②对接下来L个字符进行字典序排序

③移除剩下的字符

输入一个string S和int L,求S进行任意次变换能得到的最小字典序的结果。

范围:

S包括2~50个字符,只包含大小字符('A'~'Z')

L为[2, length(S)]

分析:

当S为"TOPCODER",L=3;最简单的的变换步骤为

①"TOPCODER"=> i = 3 => "TOPCDO"

②"TOPCDO"    =>
i = 2 => "TOCDP"

②"TOCDP"
      => i = 1 => "TCDO"

②"TCDO"
        => i = 0 => "CDT"

但第一次选择从i=3的原因不是那么显而易见,让我们再看下面一组例子的分析

当S为"ABRACADABRA", L=5;最朴素的变换步骤为

①"ABRACADABRA"=>  i =
6 =>"ABRACAAABDR"

②"ABRACAAABDR"=>
 i = 5 =>"ABRACAAABD"

③"ABRACAAABD"=>
 i = 4 =>"ABRAAAABC"

④"ABRAAAABC"
    =>  i = 3 =>"ABRAAAAB"

⑤"ABRAAAAB"=>
 i = 2 =>"ABAAAAR"

⑥"ABAAAAR"=>
 i = 1 =>"AAAAAB"

⑦"AAAAAB"=>
 i = 0 =>"AAAAA"

朴素解法:

每次对L个字符进行排序,总共要进行length(S)-L+1次;

#include <algorithm>
#include <string>
using namespace std;
class EllysSortingTrimmer
{
public:
string getMin(string S, int L)
{
for (int i = S.size()-L; i >=0 ; --i)
{
sort(S.begin()+i,S.begin()+i+L);
}
return S.substr(0,L);
}
};
算法复杂度为O(|S|*L*log(L));

进一步分析:

是否需要进行这么多次排序?

如果直接对S进行排序是否可以?不可以,"TOPCODER"的例子就是一个反例。

但从朴素解法中i=0的数据可发现,其被排序的L个字符的组成为原S字符串的第一个字符+原字符串S(1,end)中按字典序排列的前L-1个字符

因此只需要两次排序即可得到最后结果:

①对除了第一个字符的S(1,end)进行排序,排列好其前L-1小的个字符

②再将第一个字符插入到步骤①中得到的前L-1个已序字符的相应位置。

简单的实现方式如下:

#include <algorithm>
#include <string>
using namespace std;
class EllysSortingTrimmer
{
public:
string getMin(string S, int L)
{
partial_sort(S.begin()+1,S.begin()+L,S.end());
sort(S.begin(),S.begin()+L);
return S.substr(0,L);
}
};

算法复杂度为O(|S|*log(|S|);

500pt:

题意:给定一个变换规则:对一个长度为字符串letters,最大距离为maxDistance,可对该字符串进行变换生成新的字符串S,新生产的字符串S中的每一个字符的index与原字符串letters相应的字符的index相差不超过(小于等于)maxDistance。

输入一个string letters和一个最大距离int maxDistance,求变换后字典序最小的结果。

范围:

letters包含1~50个字符,只是'A'~'Z'

maxDistance~[1,9]

分析:

要求字典序最小,想到用贪心,对于新字符串S上index位上的选择,

①如果原始位中index-maxDistance位字符还没有被使用,那么就选择,不然的话后来就没有机会给他用了,因为后面再用到的话,其距离就会大于maxDistance

②否则的话,选从index-maxDistance~index+maxDistance中未使用过的最小字典序的一个,如果有相同的话,选择序号最小的

代码实现如下:

#include <string>
#include <vector>
#include <cmath>
using namespace std;
class EllysScrabble
{
public:
string getMin(string letters, int maxDistance)
{
vector<bool> flag(letters.size(), false);
string ret;
for (int index = 0; index < (int)letters.size(); ++index)
{
if (index-maxDistance >= 0 && !flag[index-maxDistance])
{
ret.push_back(letters[index-maxDistance]);
flag[index-maxDistance] = true;
}
else
{
char minChar = 'Z' + 1;
int pos = -1;
for (int i = max(0, index-maxDistance); i <= min((int)letters.size()-1, index+maxDistance); ++i)
{
if (!flag[i] && minChar > letters[i])
{
minChar = letters[i];
pos = i;
}
}
ret.push_back(minChar);
flag[pos] = true;
}
}
return ret;
}
};算法复杂度为O(N*maxDistance);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息