개념:
(조세퍼스 문제( 요세푸스 문제(Josephus problem), 요세푸스 순열(Josephus permutation) ) :
n과 k가 자연수이고, k < n이라고 가정한다. n명이 동그랗게 모여있을 때 임의의 한 명부터 순서를 세어 k번째 사람을 모임에서 제외한다. 남은 n-1명에서 다시 다음 사람부터 순서를 세서 k번째 사람을 모임에서 제외한다. 이것을 아무도 남지 않을 때까지 계속해서 반복한다. 이때 모임에서 제외되는 사람의 순서를 (n, k) 요세푸스 순열이라고 하며 마지막으로 제외되는 사람을 구하는 문제를 요세푸스 문제라고 한다.
예를 들어 (7,3) 요세푸스 순열은 {3,6,2,7,5,1,4}이며 4번째 위치한 사람이 마지막으로 제외되게 된다.)
=======================================================================================
1158번 문제
조세퍼스 문제는 다음과 같다.
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 ≤ 5,000)
출력
예제와 같이 조세퍼스 순열을 출력한다.
예제 입력/출력
입력 | 출력 |
---|---|
7 3 | <3, 6, 2, 7, 5, 1, 4> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | package a_1158; import java.util.Scanner; public class Main { public static void main(String[] args) { int n;//원형 연결 리스트 크기 N 은 전체 사람 수 int m;//M번째 사람마다 제거 Scanner sc = new Scanner(System.in); n = sc.nextInt(); m = sc.nextInt(); circular_linked_list cyclelist = new circular_linked_list();//원형 연결 리스트 생성 for (int i = 1; i <= n; i++) { cyclelist.addLast(i);//노드 생성 } cyclelist.startDelete(n,m);//삭제 시작 } } class circular_linked_list {//원현 연결 리스트 Node head;// 첫번째 노드를 가리키는 필드,변수,참조값 Node tail;// 마지막 노드를 가리키는 필드,변수 int size = 0; // 엘리먼트 갯수 class Node{ Object data;//데이터가 저장될 변수-실제 저장값 Node next;//다음 노드를 가리키는 변수,참조값 public Node(Object input) {//객체생성 초기화 this.data = input; this.next = null;//생성시는 미정 } } public void addFirst(Object input){//머리에 추가 Node newNode = new Node(input);//노드를 생성 newNode.next = head;//새로운 노드의 다음 노드로 해드 지정 head = newNode;//헤드로 새로운 노드를 지정 size++; if(head.next == null){ tail = head; head.next = tail; tail.next = head; } else { tail.next = head; } } public void addLast(Object input){//꼬리에 추가 if(size == 0){//리스트의 노드가 하나도 없다면 첫번째 노드를 추가하는 메소드를 사용. addFirst(input); } else {//기존 노드가 하나라도 있다면 Node newNode = new Node(input); tail.next = newNode;//마지막 노드의 다음 노드로 생성한 노드를 지정. tail = newNode; //마지막 노드를 갱신. tail.next = head; size++;//엘리먼트 개수 1 증가 } } public int size(){//리스트가 가진 데이터의수 return size; } public void startDelete(int n, int m) {//조세퍼스 삭제 시작 StringBuilder sb; sb = new StringBuilder(); sb.append("<"); int[] arr = new int[n]; int i=0; Node currentNode = null; while(size > 0) { if(size() == n) { currentNode = head; } if(m == 1) { for(int b=1; b < size(); b++) { currentNode = currentNode.next; } } else if(m > 2){ for(int j=1; j<m-1; j++) { currentNode = currentNode.next; } } Node todoDeleted = currentNode.next; Object returnData = todoDeleted.data; if(todoDeleted == tail){//삭제할려는데이터가 마지막값이라면 tail = currentNode; tail.next = head; } else { currentNode.next = currentNode.next.next; if(todoDeleted == head) {//삭제할려는 데이터가 헤드라면 head = currentNode.next; } } currentNode = currentNode.next; size--; arr[i++] = (int)returnData; } for(int k=0; k<n; k++) { sb.append(arr[k]+", "); //System.out.println(k+"="+arr[k]); } System.out.println(sb.toString().substring(0,sb.length()-2)+">"); } } | cs |
'Problem Solving > 백준' 카테고리의 다른 글
백준 2941번 (0) | 2019.01.26 |
---|---|
백준 1152번 (0) | 2019.01.26 |
백준 1316번 (0) | 2019.01.24 |
백준 10809번 (0) | 2019.01.24 |
백준 2908 상수 (0) | 2019.01.20 |