DNA 서열은 문자 'A', 'C', 'G', 'T'로 표현되며, 각 뉴클레오타이드는 다음 영향도(정수)를 가진다:
A → 1
C → 2
G → 3
T → 4
여러 개의 구간 질의가 주어졌을 때, 각 질의 [P[K], Q[K]] (양끝 포함) 구간 안에 포함된
뉴클레오타이드의 "최소 영향도"를 구하라.
입력:
문자열 S = S[0]S[1]...S[N-1], N = |S| (1 ≤ N ≤ 100,000), 문자들은 오직 'A','C','G','T'
정수 배열 P, Q (각 길이 M, 1 ≤ M ≤ 50,000), 각 원소는 0 ≤ P[K] ≤ Q[K] ≤ N-1
출력:
각 질의 K(0 ≤ K < M)에 대해, S의 부분 문자열 S[P[K]..Q[K]]에 존재하는 뉴클레오타이드들의
최소 영향도를 정수로 구해, 길이 M의 결과 배열로 반환
예시:
S = "CAGCCTA"
P = [2, 5, 0]
Q = [4, 5, 6]
질의별 해석:
[2,4] 구간의 문자: "G","C","C" → 영향도 {3,2,2} → 최소 2
[5,5] 구간의 문자: "T" → 영향도 4
[0,6] 구간의 문자: 전체 "CAGCCTA" → 'A'(1) 존재 → 최소 1
결과: [2, 4, 1]
요구사항:
효율적인 알고리즘 구현 (대규모 N, M에서 동작해야 함)
|
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
|
public class GenomicRangeQuery
{
public enum DNA
{
A = 1,
C = 2,
G = 3,
T = 4
}
public int[] solution(string S, int[] P, int[] Q)
{
// 누적합은 0부터 시작하는게 편하기 때문에, 길이를 하나 더 늘림
Dictionary<DNA, int[]> dnaCountDic = new Dictionary<DNA, int[]>()
{
{ DNA.A, new int[S.Length + 1] },
{ DNA.C, new int[S.Length + 1] },
{ DNA.G, new int[S.Length + 1] },
{ DNA.T, new int[S.Length + 1] }
};
int[] result = new int[P.Length];
for (int i = 0; i < S.Length; i++)
{
char character = S[i];
// 직전 누적 복사
dnaCountDic[DNA.A][i + 1] = dnaCountDic[DNA.A][i];
dnaCountDic[DNA.C][i + 1] = dnaCountDic[DNA.C][i];
dnaCountDic[DNA.G][i + 1] = dnaCountDic[DNA.G][i];
dnaCountDic[DNA.T][i + 1] = dnaCountDic[DNA.T][i];
// 현재 문자 반영
switch (character)
{
case 'A':
dnaCountDic[DNA.A][i + 1]++;
break;
case 'C':
dnaCountDic[DNA.C][i + 1]++;
break;
case 'G':
dnaCountDic[DNA.G][i + 1]++;
break;
case 'T':
dnaCountDic[DNA.T][i + 1]++;
break;
}
}
for (int i = 0; i < P.Length; i++)
{
int startIndex = P[i];
int endIndex = Q[i] + 1; // 누적합 배열은 0부터 시작하기 때문에 +1
if (dnaCountDic[DNA.A][endIndex] - dnaCountDic[DNA.A][startIndex] > 0)
{
result[i] = (int)DNA.A;
}
else if (dnaCountDic[DNA.C][endIndex] - dnaCountDic[DNA.C][startIndex] > 0)
{
result[i] = (int)DNA.C;
}
else if (dnaCountDic[DNA.G][endIndex] - dnaCountDic[DNA.G][startIndex] > 0)
{
result[i] = (int)DNA.G;
}
else
{
result[i] = (int)DNA.T;
}
}
return result;
}
}
|
cs |
'코딜리티 > Lesson' 카테고리의 다른 글
| CountingDiv (0) | 2025.09.17 |
|---|---|
| PassingCars (누적합) (0) | 2025.09.17 |
| MaxCounters (지연 갱신) (0) | 2025.09.15 |
| PermCheck (순열) (0) | 2025.09.15 |
| FrogRiverOne (0) | 2025.09.15 |