코딩테스트
슬라이딩 윈도우를 이용한 문제 풀이 - DNA 비밀번호
개발자 포비
2023. 2. 8. 22:48
* Do it 코딩테스트를 참고하였습니다. - 백준 온라인 저지 12891번
슬라이딩 윈도우라는 개념은 2개의 포인터를 이용해 범위를 지정하고, 해당 범위의 크기를 유지하며 이동하면서 문제를 해결하는 방법을 뜻합니다. 전에 포스팅한 투 포인터와는 범위의 크기가 달라지지 않는다는 차이가 있지만 비슷한 부분이 존재합니다.
해당 문제는 입력으로 주어지는 문자열에서 비밀번호를 만들 수 있는 조합의 개수를 찾는 문제입니다. 또다른 입력 값으로 받아지는 DNA별 필요 개수들을 확인하여 필요 개수들을 모두 만족하는 배열의 조합을 찾는 것이 문제의 포인트입니다.
일정한 범위(비밀번호의 크기)를 가지는 두 포인터를 가지고 각 포인터를 한 칸씩 이동하면서 검사를 하면서 비밀번호에 추가되는, 그리고 사라지는 문자에 대한 필요 개수와 비밀번호에 존재하는 각 문자들의 개수를 비교하여 조건을 충족하는 경우에 결과값에 1을 추가하는 방식으로 탐색을 이어간다.
아래는 위의 내용을 통해 작성한 코드입니다.
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
string input; // DNA 문자열
int N, M; // 문자열의 길이, 부분 문자열의 길이
vector<int> Count(4, 0); // ACGT가 각각 몇개 필요한지 담긴 배열
vector<int> ACGT(4, 0); // 현재 검색중인 배열의 ACGT가 각각 몇개가 들어있는지 담긴 배열
int result = 0;
int correct = 0;
void Add(char c)
{
int index = -1;
switch (c)
{
case 'A':
index = 0;
break;
case 'C':
index = 1;
break;
case 'G':
index = 2;
break;
case 'T':
index = 3;
break;
}
ACGT[index]++;
if (ACGT[index] == Count[index]) correct++;
}
void Remove(char c)
{
int index = -1;
switch (c)
{
case 'A':
index = 0;
break;
case 'C':
index = 1;
break;
case 'G':
index = 2;
break;
case 'T':
index = 3;
break;
}
if (ACGT[index] == Count[index]) correct--;
ACGT[index]--;
}
int main()
{
cin >> N >> M;
cin >> input;
for (int i = 0; i < 4; i++)
{
cin >> Count[i];
if (Count[i] == 0) correct++;
}
for (int i = 0; i < M; i++)
{
Add(input[i]);
}
if (correct == 4)
result++;
for (int i = M; i < N; i++)
{
Add(input[i]);
Remove(input[i - M]);
if (correct == 4) result++;
}
cout << result << endl;
return 0;
}
이렇게 DNA 비밀번호 문제에 대한 풀이를 마치겠습니다. 포바~!