문제
조세퍼스 문제는 다음과 같다.
1번부터 N번까지 N명의 사람이 원을 이루면서 앉아있고, 양의 정수 M(≤ N)이 주어진다. 이제 순서대로 M번째 사람을 제거한다. 한 사람이 제거되면 남은 사람들로 이루어진 원을 따라 이 과정을 계속해 나간다. 이 과정은 N명의 사람이 모두 제거될 때까지 계속된다. 원에서 사람들이 제거되는 순서를 (N, M)-조세퍼스 순열이라고 한다. 예를 들어 (7, 3)-조세퍼스 순열은 <3, 6, 2, 7, 5, 1, 4>이다.
N과 M이 주어지면 (N,M)-조세퍼스 순열을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 N과 M이 빈 칸을 사이에 두고 순서대로 주어진다. (1 ≤ M ≤ N ≤ 1,000)
출력
예제와 같이 조세퍼스 순열을 출력한다.
예제 입력
7 3
예제 출력
<3, 6, 2, 7, 5, 1, 4>
힌트
출처
- 문제를 만든 사람: baekjoon
1, 2, 3, 4, 5, 6 ......... n-2, n-1, n이 있다고 해보자.
3번째 순서를 계속 죽인다고 해본다면 처음에 죽이면 4번째 있는 사람이 첫번째 순서가 된다.
그리고 1, 2번째는 있던 사람들은 순서가 아래와 같이 뒤로 밀리는 것을 알 수 있다.
4, 5, 6 ....... n-2, n-1, 1, 2
한번 더 죽여보자. 6이 죽는다.
7, 8, 9 ..... n-2, n-1, 1, 2, 4, 5 와 같이 된다.
그렇다면 그냥 죽이고, 앞에 있는 것들을 뒤로 다시 넣어주면 되지 않은가?
큐나 데큐를 이용해서 앞에 있는 것을 팝시키고 뒤로 푸시하면 되는 것이다.
그러면 간단히 문제가 해결 된다.
import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.ArrayDeque; import java.util.Deque; import java.util.StringTokenizer; public class Main { public static void main(String[] args) throws Exception{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); Dequedeque = new ArrayDeque (); StringBuilder sb = new StringBuilder("<"); StringTokenizer st = new StringTokenizer(br.readLine()," "); int n = Integer.parseInt(st.nextToken());//n번까지의 수 int m = Integer.parseInt(st.nextToken());//제거할 수(m번쨰) for(int i = 1; i <= n; i++){ deque.add(i); } while(!deque.isEmpty()){ for(int i = 0; i < m -1; i++){//제거할 수 m의 앞에 있는 수는 뒤로 가야하기 때문에 m-1로 deque.addLast(deque.removeFirst());//(덱 안에 있는 첫번째 자릿수를 제거해서) 마지막 자리에 추가 - 자료구조 '덱'의 원리 이해 } sb.append(deque.removeFirst() + ", "); } System.out.println(sb.toString().substring(0, (sb.length()-2)) + ">");//마지막 수에는 ', '이 필요 없기 때문에 substring 사용 } }
push, pop이 반복적으로 이용해지면 데이터가 클 경우 퍼포먼스 측면에서 매우 안 좋다고 한다.
따라서 다른 방법 사용
import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.StringTokenizer; public class Main { public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); ArrayList<Integer> list = new ArrayList<Integer>(); StringBuilder sb = new StringBuilder("<"); StringTokenizer st = new StringTokenizer(br.readLine(), " "); int n = Integer.parseInt(st.nextToken()); int m = Integer.parseInt(st.nextToken()) - 1;// 3번째 자리는 배열 인덱스로 2번째 자리 for (int i = 1; i <= 7; i++) { list.add(i); } int index = 0; while (!list.isEmpty()) { index += m; if (index >= list.size()) { index %= list.size(); } sb.append(list.remove(index) + ", ");// 관련 index자리가 제거되면 제거 자리 후의 // 인덱스는 한 칸씩 앞으로 옴 } System.out.println(sb.toString().substring(0, sb.length() - 2) + ">"); } }
내용출처:http://mygumi.tistory.com/57
'알고리즘(Java) > 덱' 카테고리의 다른 글
백준 1021번 회전하는 큐 (0) | 2017.11.29 |
---|---|
백준 10866 덱 (0) | 2017.11.28 |
[자료구조]덱(Deque) (0) | 2017.11.23 |