1230. 암호문3
Code Battle (`23 동계 대학생 S/W 알고리즘 특강 기초학습 문제)
본 게시글은 개인 학습 용도로 작성한 게시글입니다.
(문제 출처: SW Expert Academy)
- 원소들을 추가/제거해야 하는 빈도가 잦으므로 Array보다는 Linked list를 사용하는 것이 적합.
std::list
의 Iterator를 다룰 때, Iterator를 $n$칸 전진시키기 위해 $O(n)$의 시간이 걸림에 유의하여, 최대한 적은 횟수로 Iterator를 전진 시키도록 구현.I
삽입 명령 시 $x$번 위치 부터 총 $y$개의 원소를list::insert()
로 하나 씩 넣게 되면, 총 $T(xy+\frac{1}{2}y^2)$의 시간이 소요된다.- 별도의 리스트1를 생성하여 총 $y$개의 원소를
list::push_back()
으로 $T(y)$에 삽입하고,list::splice()
를 이용하여 기존의 리스트와 $T(x+y)$에 병합할 경우, 동일한 작업을 $T(x+2y)$ 시간에 수행 할 수 있다.
- Singly-linked list
std::forward_list
대신 Doubly-linked liststd::list
를 사용하여, 사용빈도가 높은push_back()
연산을 $O(1)$ 시간에 수행 할 수 있도록 함.
#include <list>
#include <iostream>
#define MAX_N 4000
#define MAX_M 500
using namespace std;
void solveTestCase()
{
int codeCount, operationCount;
char operationType;
int i, x, y, s;
string code;
list<string> codes;
list<string> codeSnippets;
list<string>::iterator start, end;
cin >> codeCount;
for (i = 0; i < codeCount; i++) {
cin >> code;
codes.push_back(code);
}
cin >> operationCount;
for (i = 0; i < operationCount; i++) {
cin >> operationType;
switch (operationType) {
case 'I':
cin >> x >> y;
codeSnippets.clear();
for (s = 0; s < y; s++) {
cin >> code;
codeSnippets.push_back(code);
}
codes.splice(next(codes.begin(), x), codeSnippets);
break;
case 'D':
cin >> x >> y;
start = end = next(codes.begin(), x);
advance(end, y);
codes.erase(start, end);
break;
case 'A':
cin >> y;
for (s = 0; s < y; s++) {
cin >> code;
codes.push_back(code);
}
break;
default:
break;
}
}
start = end = codes.begin();
advance(end, 10);
while (start != end) {
cout << *start << ' ';
start++;
}
return;
}
void solve()
{
for (int testCaseNo = 1; testCaseNo <= 10; testCaseNo++) {
cout << '#' << testCaseNo << ' ';
solveTestCase();
cout << '\n';
}
return;
}
int main(int argc, char** argv)
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
freopen("sample_input.txt", "r", stdin);
freopen("sample_output.txt", "w", stdout);
solve();
return 0;
}
코드에서는
list<string> codeSnippets
이다. ↩