본문 바로가기

코딩테스트

[백준 2164번] [JAVA] 카드 2

728x90

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

 

2164번: 카드2

N장의 카드가 있다. 각각의 카드는 차례로 1부터 N까지의 번호가 붙어 있으며, 1번 카드가 제일 위에, N번 카드가 제일 아래인 상태로 순서대로 카드가 놓여 있다. 이제 다음과 같은 동작을 카드가

www.acmicpc.net

 

문제를 요약하자면..

 

카드 장수인 N을 입력받아야합니다.
1부터 N까지의 번호가 적힌 카드 N장을 가장 큰 수부터 바닥에 깔아서 쌓아올렸다고 생각했을 때,
  1) 맨 윗장은 버리고
  2) 버린 후의 맨 윗장은 가장 바닥에 깔아준다.
위와 같은 패턴을 반복하다가 1장이 되었을 때 마지막 카드의 번호를 출력해야합니다.

 

이번 문제는 Queue를 이용하여 풀어야했습니다.

 

Queue는 FIFO의 선입선출이라는 특징을 가지고 있습니다.

 

Queue의 함수를 간단히 정리해보겠습니다.

우선 Queue를 사용하기 위해서는

Queue<Interger> example = new LinkedList<>(); // Integer 타입으로 선언 하는 경우

Queue<String> example = new LinkedList<String>(); // String타입으로 선언하는 경우

Queue<Character> example = new LinkedList<Character>(); // Character타입 선언

위와 같이 입력하여 불러와야합니다.

Queue 에 값을 추가하는 메소드는 .add() 와 .offer()이 있으며

                 값을 삭제하는 메소드는 .poll()과 .remove() 가 있습니다.

                 여기서 poll과 remove는 Queue의 맨 앞의 값을 삭제해줍니다.

                 괄호 안에 특정 값을 넣으면 해당하는 값을 삭제해줍니다.

이외에는 Queue의 Index 값을 삭제하는 .clear()과 Queue의 첫번째 값을 참조하는 .peek() 도 있습니다.

 

아래 코드에서는 1부터 N의 번호를 가진 카드를 Queue에 입력할 때 .offer()사용하였습니다.

또한 맨 윗장을 제거해줄 때 .poll()을 사용해주었습니다. 

 

쌓여있는 카드가 1장이 아닐때 while문 안에서 패턴을 돌게 해주고 패턴 중 카드를 버린 후에

1장이 되는 경우를 생각하여 if문으로 조건을 걸어서 while문을 중간에 나올 수 있도록 해주었습니다.

카드가 1장이 되었을 때 Queue 안에 남아있는 마지막 카드를 호출하며 끝나게됩니다.

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class num2164 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
        	// Queue
		Queue<Integer> queue = new LinkedList<>();
		
		// queue 안에 1부터 n까지 입력 받기
		for( int i = 1; i <= n; i++ ) {
			queue.offer(i);
		}
		// queue 안의 카드가 1장이 아니라면 패턴 반복
		while(queue.size() != 1) {
			queue.poll();
            	// 맨 윗장을 제거했을때 queue의 카드가 1장이 되었으면 while문 빠져나가도록
			if(queue.size() == 1) {
				break;
			}
			queue.offer(queue.poll());
		}
		System.out.println(queue.poll());
	}
}