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次;
进一步分析:
是否需要进行这么多次排序?
如果直接对S进行排序是否可以?不可以,"TOPCODER"的例子就是一个反例。
但从朴素解法中i=0的数据可发现,其被排序的L个字符的组成为原S字符串的第一个字符+原字符串S(1,end)中按字典序排列的前L-1个字符
因此只需要两次排序即可得到最后结果:
①对除了第一个字符的S(1,end)进行排序,排列好其前L-1小的个字符
②再将第一个字符插入到步骤①中得到的前L-1个已序字符的相应位置。
简单的实现方式如下:
算法复杂度为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);
题意:给定一个变换规则:对一个长度为字符串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);
相关文章推荐
- Topcoder open 2015 Round 1A 250 Similars 枚举 + 状压
- Topcoder Open Match 2017 R1B
- 2014 Collage Tour - 2014 Topcoder Asia Competition B
- Topcoder Open 2016 R1A
- 2010 TopCoder Open Algorithm Competition Qualification Rounds 1
- TopCoder Open 2016 R2B
- topcoder Single Round 624(500)
- location.href、parent.location.href、top.location.href、 window.open实现页面跳转
- BZOJ3536 : [Usaco2014 Open]Cow Optics
- Top 10 Open Source Tools for eActivism
- top,self,parent,open,href,location 详细解释
- USACO2014 Open Cow Optics
- OpenText Documentum Administrator / Webtop XXE Injection
- Top 77 R posts for 2014 (+R jobs)
- Topcoder problem - LetterInterchange
- TopCoder HowEasy
- Coder-Strike 2014 - Round 1
- Coder-Strike 2014 - Finals (online edition, Div. 2) C题
- TopCoder Practices: NotchedWoodBarsPuzzle