[문제 위치]
https://www.acmicpc.net/problem/11504
[문제 풀이]
이 알고리즘은 원형으로 된 돌림판에서 시작 위치를 바꿔가며 M자리의 숫자를 추출하고, 그 숫자가 주어진 범위 X 이상 Y 이하에 해당하는지를 판단하여 조건을 만족하는 경우의 수를 세는 방식이다. 먼저 입력으로 돌림판의 칸 수 N과 숫자의 길이 M, 그리고 범위의 시작값 X와 끝값 Y가 주어진다. X와 Y는 자릿수마다 분리되어 주어지기 때문에 이를 문자열로 변환하여 비교 연산에 사용할 수 있도록 처리한다.
그다음, 돌림판은 원형이므로 예를 들어 마지막 칸에서 시작해서 M개의 숫자를 추출하려면 처음으로 다시 돌아가야 하므로, 돌림판 숫자를 M−1칸만큼 뒤에 덧붙여 확장 배열을 만든다. 이렇게 하면 배열 범위를 벗어나지 않고도 어디에서나 M개의 숫자를 시계방향으로 추출할 수 있게 된다.
이제 0번 위치부터 N−1번 위치까지 가능한 모든 시작점을 기준으로 M개의 숫자를 추출하고, 이를 문자열로 만들어 Z라고 한다. 이 Z가 X 이상이고 Y 이하인지를 문자열 비교를 통해 판단한 뒤, 조건을 만족한다면 카운트를 증가시킨다. 문자열 비교를 사용하는 이유는 숫자가 0으로 시작할 수 있기 때문에 정수형으로 변환하면 값이 달라질 수 있기 때문이다.
결과적으로, 돌림판의 각 칸에서 시작해 만든 모든 M자리 숫자 중에서 X와 Y 사이에 속하는 숫자의 개수를 출력하면 된다. 이때 같은 숫자라도 시작 위치가 다르면 서로 다른 경우로 인정되므로 중복을 허용해 센다.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main() {
int T;
cin >> T;
while (T--) {
int N, M;
cin >> N >> M;
vector<int> X(M), Y(M), wheel(N);
for (int i = 0; i < M; ++i) cin >> X[i];
for (int i = 0; i < M; ++i) cin >> Y[i];
for (int i = 0; i < N; ++i) cin >> wheel[i];
string Xs, Ys;
for (int d : X) Xs += char(d + '0');
for (int d : Y) Ys += char(d + '0');
vector<int> extended = wheel;
extended.insert(extended.end(), wheel.begin(), wheel.begin() + M - 1);
int count = 0;
for (int i = 0; i < N; ++i) {
string Z;
for (int j = 0; j < M; ++j)
Z += char(extended[i + j] + '0');
if (Xs <= Z && Z <= Ys)
++count;
}
cout << count << '\n';
}
return 0;
}'문제 풀이 > 문제 풀이(BOJ)' 카테고리의 다른 글
| [Silver V] K-세준수 (0) | 2025.08.10 |
|---|---|
| [Silver V] 직사각형 - 15687 (1) | 2025.08.08 |
| [Silver V] 젓가락 - 24228 (0) | 2025.08.06 |
| [Silver V] 연도 진행바 - 1340 (1) | 2025.08.05 |
| [Silver V] 메시지 - 1384 (2) | 2025.08.03 |