Comment detail
情報オリンピック2007年度国内本選問題2 (Nested Flatten)両方の文字列から接尾辞配列を作って処理するようにしたら、若干高速化しました。(手元で判定データ 2-6 が 17秒 => 10秒。このマシンはPen2-266で遅いんですが、それを差し引いても大会のマシンで1秒制限を満たすか怪しいです)
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | #include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <string.h> // strcmp()
#define REP(i, b, e) for (size_t i = b; i < e; ++i)
bool compare_str(const char* s1, const char* s2)
{
return strcmp(s1, s2) < 0;
}
void make_suffix_array(const std::string& s, std::vector<const char*>& v)
{
v.resize(s.size());
REP(i, 0, s.size())
{
v[i] = s.c_str() + i;
}
std::sort(v.begin(), v.end(), compare_str);
}
typedef std::vector<const char*>::const_iterator Iter;
void skip_empty_string(Iter& beg, Iter end, size_t depth)
{
while (beg != end && (*beg)[depth] == '\0')
{
++beg;
}
}
void find_range(Iter& beg, Iter& end, size_t depth, char c)
{
while (beg != end && (*beg)[depth] < c)
{
++beg;
}
Iter cur = beg;
while (cur != end && (*cur)[depth] == c)
{
++cur;
}
end = cur;
}
void traverse(Iter beg1, Iter end1, Iter beg2, Iter end2, size_t depth, size_t& max_depth)
{
skip_empty_string(beg1, end1, depth);
skip_empty_string(beg2, end2, depth);
while (beg1 != end1 && beg2 != end2)
{
const char c = (*beg1)[depth];
Iter the_beg1 = beg1, the_end1 = end1;
find_range(the_beg1, the_end1, depth, c);
Iter the_beg2 = beg2, the_end2 = end2;
find_range(the_beg2, the_end2, depth, c);
if (the_beg1 != the_end1 && the_beg2 != the_end2)
{
max_depth = std::max(max_depth, depth + 1);
traverse(the_beg1, the_end1, the_beg2, the_end2, depth + 1, max_depth);
}
beg1 = the_end1;
beg2 = the_end2;
}
}
int main()
{
std::string s1, s2;
std::getline(std::cin, s1);
std::getline(std::cin, s2);
std::vector<const char*> v1, v2;
make_suffix_array(s1, v1);
make_suffix_array(s2, v2);
size_t max_depth = 0;
traverse(v1.begin(), v1.end(), v2.begin(), v2.end(), 0, max_depth);
std::cout << max_depth << std::endl;
}
|




ocean
#5855()
[
C++
]
Rating0/0=0.00
いくつかのデータで1秒制限を満たしてないと思いますが、とりあえず接尾辞配列で。
see: 接尾辞配列
Rating0/0=0.00-0+
1 reply [ reply ]