출처: https://www.acmicpc.net/problem/1158
문제
요세푸스 순열을 구현해라!
문제의 요점을 살펴보면,
입력받은 첫번쨰 값 N 명의 사람이 1부터 N 까지 차례대로 원을 이루어 앉아있다.
이후 입력 받은 두번째 값 K 번쨰 사람이 사라지게 된다. 해당 과정은 N 명의 사람이 모두 제거될 때까지 계속된다.
원에서 사람이 제거되는 순서를 (N,K) 라고 한다.
예제 입출력
예시로 제시된 입력문을 살펴보면,
입력 값 7 과 3은 "7명의 사람이 원을 둘러 앉아있고, 3번째 사람이 제거 된다." 라고 이해할 수 있다.
예제 입력문에 대한 출력 값을 살펴보면,
위와 같은 과정을 거친 것을 확인할 수 있다.
출력 과정에 대해 살펴보면,
배열의 각 원소들은 1 부터 N 번까지 차례대로 가진다. N 값은 1 부터 시작하기 때문에, 해당 배열의 인덱스 값은 N + 1 번까지 있을 것이다.
최초에 K 번째 요소가 삭제되게 되면 삭제된 값의 바로 다음 값부터 다시 삭제할 값을 카운트 한다. 해당 과정을 N 만큼의 크기를 가진 배열이 전부 없어질 때까지 실행하게 된다.
과정 자체는 굉장히 간단한데, 어떻게 구현할지에 대해 생각해볼 필요가 있었다.
Main
사용 알고리즘
자료구조와 큐
먼저 '큐' 라는 자료구조는 '스택' 과는 반대되는 자료구조이다.
먼저 들어간 값이 가장 먼저 나오는 형태를 띄고 있는데, 큐에도 여러가지 종류가 있었다.
참고한 자료는 아래에 링크를 걸어두겠다.
우선 문제에 제시된 입력값들을 받아보겠다.
Scanner sc = new Scanner(System.in);
int N = sc.nextInt(); // N 명의 사람
int K = sc.nextInt(); // K 번째 사람이 삭제
이후 N 만큼의 크기를 가지는 배열을 생성해야하는데, 각 배열의 원소들은 1~N까지 이다.
일반적인 상황이라면 arr[] 배열 을 사용했겠지만, 이번 문제에서는 Queue 를 이용할 것이기 때문에 Queue 객체를 생성해, 1~N 까지의 값을 삽입해보겠다.
Queue<Integer> q = new LinkedList<>(); // 큐 생성
// 위에서 생성된 큐에 1~N까지의 값 삽입
for (int i = 1; i <= N; i++) {
q.offer(i); //offer 는 큐에 값을 입력하는 메서드이다.
}
이제 생성한 q 안에 값이 1개만 남을 때까지 K 번째 값을 빼는 반복문을 만들어야한다.
while(!q.isEmpty()){ // q 안에 값이 없을 때까지 실행
for(int i = 0; i<K; i++){
if(i == K-1) // 만약 i 가 K -1 이랑 같다면 ex> K = 3, i = 3 -> 결과들을 누적할 ArrayList 에 q 의 헤드 값을 추가한다.
result.add(q.poll());
else{
q.offer(q.poll());
}
}
}
이후 간단한 형식을 갖춘 결과값을 출력해주면 문제를 해결할 수 있다.
System.out.print(" < ");
for (int i=0; i<N-1; i++){ //삭제된 값 출력문
System.out.print(result.remove(0) + " , ");
}
System.out.print(result.remove(0) + " > ");
아래는 전체코드이다.
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Scanner;
public class Josephus {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = (Integer)sc.nextInt(); // N 명의 사람
int K = (Integer)sc.nextInt(); // K 번째 사람이 삭제
Queue<Integer> q = new LinkedList<>(); // 큐 생성
List<Integer> result = new ArrayList<>(); // 나중에 결과를 보여줄 ArrayList
// 위에서 생성된 큐에 1~N까지의 값 삽입
for (int i = 1; i <= N; i++) {
q.offer(i); //offer 는 큐에 값을 입력하는 메서드이다.
}
while(!q.isEmpty()){ // q 안에 값이 없을 때까지 실행
for(int i = 0; i<K; i++){
if(i == K-1) // 만약 i 가 K -1 이랑 같다면 ex> K = 3, i = 3 -> 결과들을 누적할 ArrayList 에 q 의 헤드 값을 추가한다.
result.add(q.poll());
else{
q.offer(q.poll());
}
}
}
System.out.print(" < ");
for (int i=0; i<N-1; i++){ //삭제된 값 출력문
System.out.print(result.remove(0) + " , ");
}
System.out.print(result.remove(0) + " > ");
}
}
참고사이트
큐 관련 설명: https://kwin0825.tistory.com/54
[자료구조] 큐(Queue)
큐 (Queue) - 스택과 마찬가지로 삽입과 삭제의 위치가 제한된 유한 순서 리스트 - 선입선출 구조(FIFO, First-In-First-Out) : 삽입 순으로 나열되어 가장 먼저 삽입한 원소가 가장 먼저 삭제된다. 삭제 ←
kwin0825.tistory.com
'personal 과제 > junheeee'personal' 카테고리의 다른 글
백준 1269 대칭 차집합 (0) | 2024.10.13 |
---|---|
백준.5622 다이얼 (0) | 2024.10.02 |