본문 바로가기

알고리즘(Java)/덱

백준 1158 조세퍼스 문제 0



 

문제

조세퍼스 문제는 다음과 같다.

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>

힌트

출처

 

 

 

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));
		
		Deque deque = 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