백준/덱

2346 풍선 터뜨리기

have a good time 2022. 5. 12. 19:41

1. 풀이

 

덱을 이용해서 풀었다.

 

예제를 가지고 풀이해 보겠다.

 

<예제>

5

3 2 1 -3 -1

 

 

 

1. 입력값 받기

 

코드에서

클래스 Balloon 을 만든다.

변수 number, value 를 갖는다.

number : 풍선 번호, value : 풍선 안 종이에 적혀있는 값

 

위의 예제에서

 

number => 1  2  3  4  5

value =>    3  2  1  -3 -1

 

 

 

일단 입력값을 Balloon 객체에 맞게 만든 뒤  덱 (input) 에 넣는다.

즉, (numver, value) 형태이므로, 

(1,3) (2,2) (3,1) (4,-3) (5,-1) 이 들어감.

 

 

2. while 문

 

 

예시로 설명하면,

 

1) 

현재 덱의 상태는 (1,3) (2,2) (3,1) (4,-3) (5,-1) 이다.

(1,3) 이 덱의 앞쪽, (5,-1) 쪽이 덱의 뒤쪽이다.

풍선이 원형으로 놓여있다고 했으므로 결국 덱의 앞쪽과 뒤쪽이 연결되어 있다고 생각하고 풀면된다.

 

제일 처음에는 1번 풍선을 터뜨린다고 했다.

즉 덱의 맨 앞에 있는 value = 3을 갖는 Balloon 객체

(1,3) 을 덱에서 꺼낸다.

덱에서 꺼낸다는 것은 풍선을 터뜨린다는 것이다.

 

=> 최종 덱 상태 : (2,2) (3,1) (4,-3) (5,-1) 

 

터진 풍선의 번호를 차례대로 정답으로 나열하라고 했으므로

answer(정답) : 1

(일단 1번 풍선만 터뜨렸으므로 1 표시)

 

2) 

위에서 value=3 인 풍선을 터뜨렸고, value가 양수이기 때문에 오른쪽으로 3번 이동한 풍선을 다음으로 터뜨리면 된다.

(2,2)는 오른쪽으로 한 번 이동한 것이고, (3,1)은 두 번, (4,-3) 이 세 번 이동한 것이다.

그러면 (4,-3) 을 덱에서 꺼내야 되는데,

그 앞에 있는 

 

(2,2), (3,1) 은 덱의 앞에서 꺼내서 뒤에 넣어준다.

=> 덱 : (4,-3), (5,-1), (2,2), (3,1)

 

그 후 (4,-3) 을 꺼낸다.

 

=> 최종 덱 상태 : (5,-1), (2,2), (3,1)

answer(정답) : 1,4

 

 

3)

위에서 (4,-3) 을 꺼냈으므로

그 다음 터뜨릴 풍선은

왼쪽으로 3번 이동한 풍선이다.

현재 위치에서 왼쪽으로 한 번 이동하면, (3,1)

왼쪽으로 한 번 더 이동하면 (2,2)

왼쪽으로 한 번 더 이동하면 (5,-1) 이다.

즉, (5,-1) 을 꺼낸다.

 

그런데 이 과정은 2)번 과정이랑 반대이다. 2번은 풍선 오른쪽으로 이동해서, 덱의 앞에서 꺼내서 덱의 뒤에 넣었지만,

여기서는 왼쪽 이동이므로

덱의 뒤에서 Balloon 객체를 꺼내서 덱의 앞에 넣어준다.

 

즉, 현재 덱이

(5,-1), (2,2), (3,1) 상태인데,

 

덱의 뒤에서 Balloon객체를 꺼내서 앞에 넣어주면 

=> 덱 : (3,1), (5,-1), (2,2)

 

덱의 뒤에서 Balloon객체를 꺼내서 앞에 넣어주면 

=> 덱 : (2,2), (3,1), (5,-1)

 

덱의 뒤에서 Balloon객체를 꺼내서 앞에 넣어주면 

=> 덱 : (5,-1), (2,2), (3,1) 이 된다.

 

즉 (5,-1) 을 꺼내면 된다.

 

=> 최종 덱 : (2,2), (3,1)

answer(정답) : 1, 4, 5

이런식으로 진행하면 된다.

 

 

3. 주의할 점

덱을 정의할 떄 LinkedList 사용 시 메모리초과 날 수 있다.

순차적인 데이터 추가, 삭제에는 ArrayList 사용이 효과적이라고 한다.

 

 

2. 최종 코드 

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.StringTokenizer;


class Balloon{
	int number;
	int value;
	
	Balloon(int number, int value) {
		this.number = number;
		this.value = value;
	}
}


public class Main {

	
	public static void main(String[] args) throws IOException {
		
		
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int N = Integer.parseInt(br.readLine());
		Deque<Balloon> input = new ArrayDeque<>();
		StringBuilder answer = new StringBuilder();
		
		StringTokenizer st = new StringTokenizer(br.readLine(), " " );
		for(int i=1; i<=N; i++) {
			
			input.addLast(new Balloon(i, Integer.parseInt(st.nextToken())));
		}
		
		
	
		boolean check = true;
		
		while(!input.isEmpty()) { 
			
		
			int a = 0;
			
			
			if(check) {
				Balloon b1 = input.removeFirst();
				a =b1.value;
				answer.append(b1.number + " ");
			}else {
				Balloon b2 = input.removeLast();
				a = b2.value;
				answer.append(b2.number + " " );
			}
			
			
			
			if(input.isEmpty()) {
				break;
				
			}else if(a >0) {
				
				check = true;
				
				while(a-->1) {
					input.addLast(input.removeFirst());
				}
				
			}else if(a<0 ) {
				
				check = false;
				
				int M = Math.abs(a);
				while(M-->1) {
					input.addFirst(input.removeLast());
				}
			}
		}
		
		
		
		System.out.println(answer.toString().trim());
	}
}

 

 

참고 블로그 : https://kwoncorin.tistory.com/92

 

[JAVA]백준 2346번: 풍선 터뜨리기

https://www.acmicpc.net/problem/2346 2346번: 풍선 터뜨리기 첫째 줄에 자연수 N(1≤N≤1,000)이 주어진다. 다음 줄에는 차례로 각 풍선 안의 종이에 적혀 있는 수가 주어진다. 편의상 0은 적혀있지 않다고 가

kwoncorin.tistory.com