[JAVA/백준] 1158번: 요세푸스 문제

👀 문제

https://www.acmicpc.net/problem/1158

👊 도전

1. 설계

  1. 큐에 값을 넣는다.
  2. k번째가 아니면 다시 뒤에 넣고, 맞으면 StringBuilder에 저장한다.

2. 구현 (성공 코드)

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
import java.util.*;
import java.io.*;
/**
 * @author HEESOO
 *
 */
class Main {
	public static void main(String[] args) throws IOException {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		int k=sc.nextInt();
		
		StringBuilder sb=new StringBuilder();
		sb.append("<");
		Queue<Integer> q=new LinkedList<>();
		for(int i=1;i<=n;i++) q.offer(i); // 큐에 삽입
		
		int cnt=0;
		while(!q.isEmpty()) {
			cnt++;
			if(cnt%k==0) sb.append(q.poll()+", "); // k번째라면
			else q.offer(q.poll()); // 아니라면 뒤에 삽입
		}
		
		sb.delete(sb.length()-2, sb.length()); // 마지막에 콤마와 띄어쓰기가 있으므로 삭제
		sb.append(">");
		System.out.println(sb.toString());
	}
}

3. 결과

실행결과 🤟 성공 🤟

4. 설명

  1. 큐를 이용한다
    • 배열이나 ArrayList의 인덱스를 가지고 for문 돌리면, 원소의 삭제 삽입이 반복되므로 오류가 발생할 수 있다.
    • 따라서 큐를 이용한다.
  2. 큐를 이용한다
    • cnt는 이제 뽑을 원소가 몇 번째 값인지 체크한다.
    • k의 배수 번째 값이라면 제거할 수 있다. 따라서 StringBuilder에 넣는다.
    • 아닐 경우 뒤에 삽입하여 순서를 다시 받는다.
    • StringBuilder 생성이 끝나면 마지막에 “, “가 들어있기 때문에 delete()를 이용하여 삭제한다.

👏 해결 완료!