먹고또자니 <거기 누구세요> 코너에서는 "돌림판"을 돌려 상품을 얻을 수 있다. 이 돌림판은 큰 원형판이 N등분되어있는 형태이다.
N등분 된 각 부분은 0부터 9사이의 숫자가 하나씩 적혀있다. 게임이 시작되면, 임의의 M자리의 수 X와 Y(X ≤ Y)가 주어진다. (단, 이 수는 0으로 시작될 수도 있다.)
그리고 참가자는 돌림판을 힘차게 돌린다. 힘차게 돌던 돌림판이 완전히 멈추게 되는 순간, 12시 방향의 스피너가 특정 부분을 가리키게 될 것이다. 거기서부터 시계방향으로 M칸 연속되는 수를 읽으면 M자리의 수 Z를 얻을 수 있다.
이때 얻은 Z가 X ≤ Z ≤ Y를 만족한다면 게임을 승리하고 Z만원을 얻을 수 있다!

예를 들어, 돌림판이 N = 8 등분되어있고, 시계방향으로 읽었을 때 [3, 7, 8, 3, 1, 9, 2, 7] 과 같다고 하자. X = 200 이고 Y = 311일 경우 "숫자 2"가 적힌 부분부터 시작한다면 Z = 273 으로 X = 200 ≤ 273 ≤ 311 = Y 를 만족하여 게임을 승리한다.
돌림판의 상태와 X, Y가 주어질 때 어느 부분부터 시작하면 게임을 승리할 수 있을 지 알 수 있다. 주어진 조건에 대해서 게임을 승리할 수 있는 가지수를 계산하는 프로그램을 작성하시오.
첫 번째 줄에 테스트케이스의 개수 T가 주어진다.
각 테스트케이스의 첫 줄에는 돌림판을 N등분할 정수 N (1 ≤ N ≤ 100)과 X, Y의 길이 M (1 ≤ M ≤ 9, M ≤ N) 이 주어진다. 그리고 다음 3개의 줄에 X의 각 자리수, Y의 각 자리수, 돌림판의 상태가 주어진다.
X와 Y의 각 자리수는 공백으로 구분되어 0~9사이의 숫자가 한자리씩 주어진다.
돌림판의 상태는 어느 부분부터 시계방향으로 읽었을 때 나타나는 순서대로 주어진다. 돌림판의 숫자도 0~9사이의 숫자가 공백으로 구분되어 주어진다.
각 테스트케이스에 대하여 한 줄씩 정답을 출력한다.
즉, 돌림판에서 X ≤ Z ≤ Y를 만족하는 M자리의 수 Z가 몇 개가 있는 지를 출력한다. 단, 같은 수라도 시작 부분이 다르다면 다른 가지수로 센다. 예를 들어, X와 Y 사이에 있는 수가 123 밖에 없는 데 돌림판에서 2번 나온다면, 1이 아닌 2를 출력한다.
3
8 3
2 0 0
3 1 1
3 7 8 3 1 9 2 7
5 2
8 8
9 9
1 3 2 5 4
6 3
0 0 0
9 9 9
1 2 3 4 5 6
1
0
6
※ 돌림판은 원으로 되어있기 때문에 시작과 끝을 알 수 없다는 걸 고려해야 한다. 즉 [1, 2, 3, 4, 5, 6, 7, 8, 9]에서 123, 234, 345, 456, 567, 678, 789가 끝이 아니고, 891, 912까지도 가능한 것이다.
여기서 문자열을 사용한 이유는 789까지 진행했을 때, 0으로 index를 옮기는 것이 아니라 앞에서 부터 문자를 하나씩 더해주고자 하기 위함이다. (0으로 index를 옮기게 되면, 언제 끝나는지 알 수 없기 때문이다.) -> 위 상황에서 912까지 진행하면 더 진행하면 안 되는데, 123, 234...로 다시 되돌아갈 수 있기 때문에 다음과 같은 방법을 사용해줬다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int cases = Integer.parseInt(br.readLine());
int N, M, X, Y;
String status, reading;
String[] input;
int count = 0;
for(int i=0; i<cases; i++) {
count = 0;
input = br.readLine().split(" ");
N = Integer.parseInt(input[0]);
M = Integer.parseInt(input[1]);
X = Integer.parseInt(br.readLine().replaceAll(" ", ""));
Y = Integer.parseInt(br.readLine().replaceAll(" ", ""));
status = br.readLine().replaceAll(" ", "");
int index = 0;
for(int j=0; j<N; j++) {
while(j+M>=status.length()) {
status += status.charAt(index);
index++;
}
reading = "";
for(int k=j; k<j+M; k++) {
reading += Character.toString(status.charAt(k));
}
if(Integer.parseInt(reading)<=Y && Integer.parseInt(reading)>=X) {
count++;
}
}
System.out.println(count);
}
}
}
오랜만에 틀리지 않고 원트에 성공한 문제! 돌림판의 상태를 어떻게 해줘야 할까가 큰 고민이었다. 이전 문제에서는 그냥 똑같은 문자열을 한 번 더 써주는 걸로 해결되는 수준이었지만, 이번에는 그렇게 할 수가 없었기 때문에 다른 방법을 생각해냈어야 했는데 다행히 금방 저 방법을 떠올렸다. 굿~ 이 문제를 이렇게 문자열로 푸는 게 맞나 싶긴하다.. 요즘 문제 풀이에 문자열을 주로 사용하고 있는데 좋은 방식인지는 잘 모르겠다..ㅜ