백준

[백준_2346번] 풍선 터뜨리기

빙수빈수 2021. 8. 11. 17:33

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

 

2346번: 풍선 터뜨리기

1번부터 N번까지 N개의 풍선이 원형으로 놓여 있고. i번 풍선의 오른쪽에는 i+1번 풍선이 있고, 왼쪽에는 i-1번 풍선이 있다. 단, 1번 풍선의 왼쪽에 N번 풍선이 있고, N번 풍선의 오른쪽에 1번 풍선

www.acmicpc.net

[문제]

 1번부터 N번까지 N개의 풍선이 원형으로 놓여 있고. i번 풍선의 오른쪽에는 i+1번 풍선이 있고, 왼쪽에는 i-1번 풍선이 있다. 단, 1번 풍선의 왼쪽에 N번 풍선이 있고, N번 풍선의 오른쪽에 1번 풍선이 있다. 각 풍선 안에는 종이가 하나 들어있고, 종이에는 -N보다 크거나 같고, N보다 작거나 같은 정수가 하나 적혀있다. 이 풍선들을 다음과 같은 규칙으로 터뜨린다.

 우선, 제일 처음에는 1번 풍선을 터뜨린다. 다음에는 풍선 안에 있는 종이를 꺼내어 그 종이에 적혀있는 값만큼 이동하여 다음 풍선을 터뜨린다. 양수가 적혀 있을 경우에는 오른쪽으로, 음수가 적혀 있을 때는 왼쪽으로 이동한다. 이동할 때에는 이미 터진 풍선은 빼고 이동한다.

 예를 들어 다섯 개의 풍선 안에 차례로 3, 2, 1, -3, -1이 적혀 있었다고 하자. 이 경우 3이 적혀 있는 1번 풍선, -3이 적혀 있는 4번 풍선, -1이 적혀 있는 5번 풍선, 1이 적혀 있는 3번 풍선, 2가 적혀 있는 2번 풍선의 순서대로 터지게 된다.

 

[입력 조건]

첫째 줄에 자연수 N(1 ≤ N ≤ 1,000)이 주어진다. 다음 줄에는 차례로 각 풍선 안의 종이에 적혀 있는 수가 주어진다. 종이에 0은 적혀있지 않다.

 

[코드]

import java.util.*;

class Balloon_2346 {
	int index; // 풍선 번호
	int value; // 적혀있는 값
	
	public Balloon_2346(int index, int value) {
		this.index=index;
		this.value=value;
	}
}

public class BaekJoon_2346 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		Deque<Balloon_2346> dq=new ArrayDeque<>();
		StringBuilder sb=new StringBuilder();
		
		// 풍선의 번호를 늘려가며 적혀있는 번호 저장
		for(int i=1;i<=n;i++) {
			int value=sc.nextInt();
			dq.add(new Balloon_2346(i,value));
		}
			
		while(!dq.isEmpty()) {
			// 덱의 제일 앞에있는 풍선의 번호를 저장
			sb.append(dq.getFirst().index+" ");
			
			// 제일 앞에있는 풍선을 꺼낸 후, 적혀있는 값 저장
			int next=dq.poll().value; 
			
			// 남아있는 풍선이 없다면 종료
			if(dq.isEmpty())
				break;
			
			// 적혀있는 값이 양수인 경우
			if(next>0) {
				for(int i=0;i<next-1;i++)
					dq.addLast(dq.pollFirst());
			}
			// 적혀있는 값이 음수인 경우
			else {
				for(int i=0;i<Math.abs(next);i++)
					dq.addFirst(dq.pollLast());
			}
		}
		
		System.out.println(sb);
	}

}

 

[고찰]

 이번 문제는 풍선이 원형으로 놓여져 있고, 풍선에 적혀있는 값이 음수일 경우 그 값 만큼 왼쪽에 있는 풍선을 터뜨려야 한다는 조건을 보고 덱을 사용해야 한다는 것을 알았다. 이렇게 어떤 자료구조를 사용해야 하는지 알고 난 후는 어렵지 않게 해결할 수 있었다. 자바의 덱 라이브러리에는 덱의 제일 앞, 뒤에 값을 삽입/삭제 할 수 있는 함수가 제공되기 때문에 이러한 함수를 사용하여 해결하였다. 

 다만 주의해야 할 점이 있었는데 풍선에 적혀있는 값이 양수일 경우 값의 -1만큼 이동해야 하고, 음수일 경우는 적혀있는 값 만큼 모두 이동해야 했다. 그 이유는 while문 아래 dq.poll() 함수의 사용으로 인해 오른쪽으로 한 칸 이동하는 상황이 생겨 음수일 경우는 적혀있는 값 모두 이동시켜주어야 한다.

'백준' 카테고리의 다른 글

[백준_11403번] 경로 찾기  (0) 2021.08.11
[백준_1789번] 수들의 합  (0) 2021.08.11
[백준_10799번] 쇠막대기  (0) 2021.08.10
[백준_1935번] 후위 표기식2  (0) 2021.08.10
[백준_2217번] 로프  (0) 2021.08.10