문제 출처 : https://www.acmicpc.net/problem/1593
언어 : Kotlin
문제 설명 :
마야 문자를 해독하는 일은 예상 외로 어려운 일이다. 현재에도 뜻이 완전히 밝혀진 마야 문자는 거의 없는 실정이며, 그나마 해독에 진척이 시작된 지는 30여 년도 되지 않았다.
마야 문자는 소리를 나타내는 여러 종류의 그림글자로 구성되는데, 이 글자들이 여러 위치에서 결합함으로써 단어를 형성한다.
마야 문자 해독을 어렵게 하는 요인 중 하나는 바로 단어를 읽는 순서이다. 마야 문자를 쓰는 고대인들은 단어를 기록할 때 특정한 규칙 대신, 그들이 보기에 좋게 보이도록 단어를 이루는 글자들을 아무렇게나 배열했다. 그렇기 때문에 고고학자들이 마야 기록에서 단어를 이루는 각 그림글자들의 발음을 알아내더라도 그 단어를 실제로 발음하는 방법은 정확히 알 수 없는 셈이다.
고고학자들은 W라는 특정 단어를 발굴 기록으로부터 찾고 있다. 그 단어를 구성하는 각 글자들은 무엇인지 알고 있지만, 이것이 고대 기록에 어떤 형태로 숨어 있는지는 다 알지 못한다.
W를 이루고 있는 g개의 그림문자와, 연구 대상인 벽화에 기록된 마야 문자열 S가 주어졌을 때, 단어 W가 마야 문자열 S에 들어있을 수 있는 모든 가짓수를 계산하는 프로그램을 작성하시오. 즉, 문자열 S안에서 문자열 W의 순열 중 하나가 부분 문자열로 들어있는 모든 경우의 수를 계산하라는 뜻이다.
입력 :
첫째 줄에 고고학자들이 찾고자 하는 단어 W의 길이 g와 발굴된 벽화에서 추출한 문자열 S의 길이 |S|가 빈 칸을 사이에 두고 주어진다. (1≤g≤3000, g≤|S|≤3,000,000) 둘째 줄에 W, 셋째 줄에 S의 실제 내용이 들어있다. 모든 문자열은 알파벳으로 이루어지며, 대소문자를 구분한다.
출력 :
첫째 줄에 W의 순열이 S 안에 있을 수 있는 형태의 개수를 출력한다.
제한 사항 :
- 시간 제한 : 2초
- 메모리 제한 : 128MB
입출력 예 :
입력 | 출력 |
4 11 cAda AbrAcadAbRa |
2 |
풀이 :
슬라이딩 윈도우 기법을 사용한다.
슬라이딩 윈도우는 고정된 일정한 사이즈로 앞부분과 뒷부분만 변경해주는 기법이다. 이는 구간이 일정하기 때문에 시작점을 알면 끝점을 알 수 있어서 투포인터와 달리 포인터가 굳이 2개가 필요하지 않다. 예를 들어 길이가 4라고 고정되었을 때 다음과 같이 구간을 탐색하게 된다.
start = 0, 🟦🟦🟦🟦⬜️⬜️⬜️
start = 1, ⬜️🟦🟦🟦🟦⬜️⬜️
start = 2, ⬜️⬜️🟦🟦🟦🟦⬜️
...
import java.io.BufferedReader
import java.io.BufferedWriter
import java.io.InputStreamReader
import java.io.OutputStreamWriter
fun main() = with(BufferedReader(InputStreamReader(System.`in`))) {
val bw = BufferedWriter(OutputStreamWriter(System.out))
val (w, g) = readLine().split(" ").map { it.toInt() }
val inputs = Array<String>(2) { readLine() }
val arr = Array(2) { IntArray(52) }
for (cur in inputs[0]) {
arrInputChar(cur, arr[0], 1)
}
var start = 0
var cnt = 0
var size = 0
for (i in inputs[1].indices) {
val cur = inputs[1][i]
arrInputChar(cur, arr[1], 1)
size++
if (size == inputs[0].length) {
if (arr[0].contentEquals(arr[1])) cnt++
arrInputChar(inputs[1][start], arr[1], -1)
start++
size--
}
}
bw.write("$cnt")
bw.flush()
bw.close()
}
fun arrInputChar(cur: Char, arr: IntArray, dif: Int) {
if (cur in 'a'..'z') arr[cur - 'a'] += dif else arr[cur - 'A' + 26] += dif
}
'백준 > 문제' 카테고리의 다른 글
23841번: 데칼코마니 (0) | 2024.05.27 |
---|---|
17502번: 클레어와 팰린드롬 (0) | 2024.05.27 |
2037번: 문자메시지 (0) | 2024.05.24 |
4378번: 트ㅏㅊ; (0) | 2024.05.24 |
31495번: 그게 무슨 코드니.. (0) | 2024.05.23 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!