[10799] 쇠막대기
시간 제한 메모리 제한 제출 정답 맞힌 사람 정답 비율
1 초 | 256 MB | 59085 | 38494 | 28586 | 65.295% |
문제
여러 개의 쇠막대기를 레이저로 절단하려고 한다. 효율적인 작업을 위해서 쇠막대기를 아래에서 위로 겹쳐 놓고, 레이저를 위에서 수직으로 발사하여 쇠막대기들을 자른다. 쇠막대기와 레이저의 배치는 다음 조건을 만족한다.
- 쇠막대기는 자신보다 긴 쇠막대기 위에만 놓일 수 있다. - 쇠막대기를 다른 쇠막대기 위에 놓는 경우 완전히 포함되도록 놓되, 끝점은 겹치지 않도록 놓는다.
- 각 쇠막대기를 자르는 레이저는 적어도 하나 존재한다.
- 레이저는 어떤 쇠막대기의 양 끝점과도 겹치지 않는다.
아래 그림은 위 조건을 만족하는 예를 보여준다. 수평으로 그려진 굵은 실선은 쇠막대기이고, 점은 레이저의 위치, 수직으로 그려진 점선 화살표는 레이저의 발사 방향이다.
이러한 레이저와 쇠막대기의 배치는 다음과 같이 괄호를 이용하여 왼쪽부터 순서대로 표현할 수 있다.
- 레이저는 여는 괄호와 닫는 괄호의 인접한 쌍 ‘( ) ’ 으로 표현된다. 또한, 모든 ‘( ) ’는 반드시 레이저를 표현한다.
- 쇠막대기의 왼쪽 끝은 여는 괄호 ‘ ( ’ 로, 오른쪽 끝은 닫힌 괄호 ‘) ’ 로 표현된다.
위 예의 괄호 표현은 그림 위에 주어져 있다.
쇠막대기는 레이저에 의해 몇 개의 조각으로 잘려지는데, 위 예에서 가장 위에 있는 두 개의 쇠막대기는 각각 3개와 2개의 조각으로 잘려지고, 이와 같은 방식으로 주어진 쇠막대기들은 총 17개의 조각으로 잘려진다.
쇠막대기와 레이저의 배치를 나타내는 괄호 표현이 주어졌을 때, 잘려진 쇠막대기 조각의 총 개수를 구하는 프로그램을 작성하시오.
입력
한 줄에 쇠막대기와 레이저의 배치를 나타내는 괄호 표현이 공백없이 주어진다. 괄호 문자의 개수는 최대 100,000이다.
출력
잘려진 조각의 총 개수를 나타내는 정수를 한 줄에 출력한다.
문제풀이
이 문제는 인접한 괄호는 레이저이고 인접하지 않는 괄호는 쇠막대기의 시작과 끝을 나타낸다.
이때 주어진 괄호에 대해 잘려지는 쇠막대기의 총 개수를 구하는 문제이다.
입력받기 및 변수 선언
입력을 받은후 열린 괄호의 수를 세기 위해 openCount와 ans를 선언한다.
Scanner sc = new Scanner(System.in);
char[] input = sc.next().toCharArray();
int openCount = 0;
int ans = 0;
열린 괄호 입력
반복문을 사용하여 ( 열린괄호가 들어온다면 openCount를 하나 증가 시켜 막대기 하나를 추가해주자.
닫힌 괄호 입력
) 닫힌괄호가 들어온다면 이전 값과 비교하여 이전값이 (이면 인접한 괄호이기에 레이저라고 판단하여 레이저를 발사하는데 이때 openCount의 개수만큼 잘린 막대기가 생성하기에 ans에 openCount를 더해주자.
만약 이전값이 )이라면 잘린 막대기가 하나이니 하나를 추가해주면된다.
for (int i = 0; i < input.length; i++) {
if (input[i] == '(') openCount++;
else {
openCount--;
if (input[i - 1] == '(')
ans += openCount;
else ans++;
}
}
전체코드
import java.util.*;
class Main
{
public static void main (String[] args) {
Scanner sc = new Scanner(System.in);
char[] input = sc.next().toCharArray();
int openCount = 0;
int ans = 0;
for (int i = 0; i < input.length; i++) {
if (input[i] == '(') openCount++;
else {
openCount--;
if (input[i - 1] == '(')
ans += openCount;
else ans++;
}
}
System.out.println(ans);
}
}
시간복잡도
이 알고리즘의 시간복잡도는 O(n)이다.
[2504] 괄호의 값
시간 제한 메모리 제한 제출 정답 맞힌 사람 정답 비율
1 초 | 128 MB | 70112 | 20362 | 15376 | 31.442% |
문제
4개의 기호 ‘(’, ‘)’, ‘[’, ‘]’를 이용해서 만들어지는 괄호열 중에서 올바른 괄호열이란 다음과 같이 정의된다.
- 한 쌍의 괄호로만 이루어진 ‘()’와 ‘[]’는 올바른 괄호열이다.
- 만일 X가 올바른 괄호열이면 ‘(X)’이나 ‘[X]’도 모두 올바른 괄호열이 된다.
- X와 Y 모두 올바른 괄호열이라면 이들을 결합한 XY도 올바른 괄호열이 된다.
예를 들어 ‘(()[[]])’나 ‘(())[][]’ 는 올바른 괄호열이지만 ‘([)]’ 나 ‘(()()[]’ 은 모두 올바른 괄호열이 아니다. 우리는 어떤 올바른 괄호열 X에 대하여 그 괄호열의 값(괄호값)을 아래와 같이 정의하고 값(X)로 표시한다.
- ‘()’ 인 괄호열의 값은 2이다.
- ‘[]’ 인 괄호열의 값은 3이다.
- ‘(X)’ 의 괄호값은 2×값(X) 으로 계산된다.
- ‘[X]’ 의 괄호값은 3×값(X) 으로 계산된다.
- 올바른 괄호열 X와 Y가 결합된 XY의 괄호값은 값(XY)= 값(X)+값(Y) 로 계산된다.
예를 들어 ‘(()[[]])([])’ 의 괄호값을 구해보자. ‘()[[]]’ 의 괄호값이 2 + 3×3=11 이므로 ‘(()[[]])’의 괄호값은 2×11=22 이다. 그리고 ‘([])’의 값은 2×3=6 이므로 전체 괄호열의 값은 22 + 6 = 28 이다.
여러분이 풀어야 할 문제는 주어진 괄호열을 읽고 그 괄호값을 앞에서 정의한대로 계산하여 출력하는 것이다.
입력
첫째 줄에 괄호열을 나타내는 문자열(스트링)이 주어진다. 단 그 길이는 1 이상, 30 이하이다.
출력
첫째 줄에 그 괄호열의 값을 나타내는 정수를 출력한다. 만일 입력이 올바르지 못한 괄호열이면 반드시 0을 출력해야 한다.
문제풀이
이 문제는 인접한 괄호가 소괄호일 경우 2를 대괄호일 경우 3이 나온다.
이때 인접하지 않는 경우는 2 * X이다. 이런것들을 어떻게 할지 알아보자.
소괄호와 대괄호를 분리하자.
입력이 올바르지 않은 경우는 -1을 출력하여 0을 출력되게 하자.
소괄호이면 2를 반환해주고 대괄호이면 3을 반환해주자.
static int delimiterToValue(char delimiter) {
if (delimiter == '(' || delimiter == ')') return 2;
else if (delimiter == '[' || delimiter == ']') return 3;
return -1;
}
필요한 변수들을 선언해보자.
문자열을 입력을 받아주고 stack, topIndex, currentMultipe, ans를 이용하려고한다.
stack은 배열을 저장해서 사용할것이다.
Scanner sc = new Scanner(System.in);
char[] input = sc.next().toCharArray();
int[] stack = new int[input.length];
int topIndex = -1;
int currentMultiple = 1;
int ans = 0;
로직을 작성해보자.
이제 열린 괄호가 입력이 되면 Stack에 열린 괄호를 넣어주자.
그리고 currentMultipe에 2이든 3이든 값을 넣어주자.
만약 오류가 있다면 0을 출력해주자.
그리고 닫힌 괄호가 입력 된다면 이전 괄호가 열려있는지 확인하고 열려있다면 currentMultiple을 더해서 값을 올려주고 그러지 않다면 분배법칙에 의해 나눠줘야한다.
for (int i = 0; i < input.length; i++) {
int delimiterValue = delimiterToValue(input[i]);
if (input[i] == '(' || input[i] == '[') {
stack[++topIndex] = delimiterValue;
currentMultiple *= delimiterValue;
}
else {
if (topIndex < 0 || stack[topIndex--] != delimiterValue) {
ans = 0;
break;
}
if (input[i - 1] == '(' || input[i - 1] == '[')
ans += currentMultiple;
currentMultiple /= delimiterValue;
}
}
'알고리즘 > Stack' 카테고리의 다른 글
[코딩테스트] [4949] 균형잡힌 세상 & [2812] 크게 만들기 (0) | 2025.02.05 |
---|