본문 바로가기

Problem Solving/백준

백준 1158 번

반응형

개념:

(조세퍼스 문제( 요세푸스 문제(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)

출력

예제와 같이 조세퍼스 순열을 출력한다.

예제 입력/출력

입력출력

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