숨막히는 알고말고/문제 풀이
[SWEA] 쇠막대기 자르기
숨숨숨
2021. 8. 5. 22:27
👀 문제 설명
로그인해야 문제를 볼 수 있다.
✍🏻풀이
스택을 사용해서 풀었다!
스택에는 String str의 인덱스를 저장해둔다.
( 를 만날 때는 stack.add를, )를 만날 때는 이 괄호가 레이저인지, 쇠막대기인지 구분해서 처리해주면 된다.
String str에 쇠막대기와 레이저의 배치를 입력받고, for문으로 str에 접근한다.
쇠막대기인지, 레이저인지 구별하는 방법은 str.charAt(i)가 ')'일 때, stack.peek()가 i - 1인지 확인하고, stack.peek()가 i - 1 이라면, 레이저라는 뜻이고, 아니면 쇠막대기라는 뜻이다. (레이저를 의미하는 괄호쌍은 인접하기 때문이다.)
레이저일 때는 먼저, stack.pop()을 한 후, stack.size()만큼 cnt에 더해주고,
쇠막대기일 때는 cnt에 1을 더해주면 되는데, 이유는 다음과 같다.
파란색 레이저일 때, 옆 괄호에서 파란색으로 체크한 부분들만 stack에 들어가있는 상태이고,
초록색 레이저일 때도, 옆 괄호에서 초록색으로 체크한 부분들만 stack에 들어가있는 상태이다.
빨간색 레이저일 때도, 옆 괄호에서 빨간색으로 체크한 부분들만 stack에 들어가있는 상태이다.
레이저가 나갈 때, 잘리는 막대기를 보면, 각각 색깔로 체크한 부분들이 괄호에서 체크한 부분들과 개수가 같은걸 알 수 있다.
노란색 ')'를 보면, 막대기가 끝났다는 표시이므로, 그 부분에 잘린 막대기 (1개)를 cnt에 더해줘야 한다.
이걸 이제 코드로 구현하면 된다..!
설명하기 어렵당..
코드
package swea;
// 쇠막대기 자르기 (https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWVl47b6DGMDFAXm )
import java.util.*;
import java.io.*;
public class SWEA_5432 {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int T;
Stack<Integer> stack;
String str;
T = Integer.parseInt(br.readLine());
for (int tc = 1; tc <= T; tc++) {
stack = new Stack<>();
str = br.readLine();
// solve
stack.add(0);
int cnt = 0;
for (int i = 1; i < str.length(); i++) {
if (str.charAt(i) == '(') {
stack.add(i);
}
else {
if (stack.peek() == (i - 1)) { // 레이저
// 레이저일 때는 stack.size()만큼 cnt에 더해준다.
stack.pop();
cnt += stack.size();
}
else { // 쇠막대기
// 쇠막대기가 끝날 때는, cnt에 1을 더해준다.
cnt += 1;
stack.pop();
}
}
}
bw.write("#" + tc + " " + cnt);
bw.newLine();
}
bw.flush();
bw.close();
}
}