문제
https://www.acmicpc.net/problem/1541
값을 최소로 만들기 위해 괄호를 어떻게 쳐야 되는지 구하는 문제.
빼기(-)를 기준으로 수들을 나눈 뒤 각각 더해서 빼주면 되는 문제다.
전략
01. 파싱
계산식을 뭐 어떻게 하라. 이런 문제는 보통 파싱만 잘해도 풀린다. 괄호를 쳐서 최소값을 구해야 하므로 - 로 묶을 수 있는 묶음을 최대한 크게 해야 한다. 따라서 -에서 다음 -가 나올 때까지의 모든 수를 묶어서 괄호를 치면 그 수가 가장 작은 수가 되므로 -를 기준으로 파싱하고 안에 있는 수들을 더한 뒤 빼면 된다.
풀이
Java
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int sum = 0;
String[] lines = br.readLine().split("-");
sum = addPlus(lines[0]);
for (int i = 1; i < lines.length; i++) {
sum -= addPlus(lines[i]);
}
System.out.println(sum);
}
private static int addPlus(String line) {
return Arrays.stream(line.split("\\+")).mapToInt(Integer::parseInt).reduce(0, Integer::sum);
}
}
br.readline()으로 입력값을 받은 뒤, String의 메서드인 split을 이용해 "-"를 기준으로 나눈 각각의 String들을 String배열 lines에 저장한다. 이때 조건에 '가장 처음과 마지막 문자는 숫자'라는 조건이 있으므로 맨 처음 수부터 -가 나올 때까지의 수는 모두 양수다. 따라서 첫번째 수들을 모두 더해서 먼저 sum이라는 변수에 넣어주었다.
그리고 lines배열의 나머지는 -를 기준으로 split한 계산식 덩어리들이기 때문에 모두 빼주면 된다.
addPlus메서드를 보면 계산식 덩어리인 String line을 파라미터로 받아서 stream배열로 만들어 준다. 이 때, Java의 split메서드의 argument는 정규표현식이며 +는 정규표현식에서 앞에 있는 문자 집합이 한번 이상 반복됨을 뜻하는 메타 문자이므로 이를 이스케이프해서 리터럴로 사용하기 위해서는 백슬래시(\)를 두번 입력해주어야 한다.
그 이후에는 각 숫자를 Integer.parseInt를 파싱하는 mapToInt와 stream배열을 하나의 결과로 산출하는 reduce를 이용해 각각을 더해 최종적으로 +로 분리하는 모든 수를 더하는 메서드가 되었다.
Python
import sys
def totalizer(str: str):
return sum(map(int, str.split("+")))
input_string_array = sys.stdin.readline().rstrip().split("-")
total = totalizer(input_string_array[0])
for i in range(1, len(input_string_array)):
total -= totalizer(input_string_array[i])
print(total)
파이썬은 훨씬 깔끔하다. 기본적인 동작원리는 자바와 같으나, 파이썬의 메서드를 이용했을 뿐이다.
Javascript (Nodejs)
function totalizer(str) {
let sum = 0;
const numbers = str.split("+");
numbers.forEach((number) => {
sum += Number.parseInt(number);
});
return sum;
}
const fs = require("fs");
let input = fs.readFileSync("/dev/stdin").toString();
input = input.split("-");
let result = totalizer(input[0]);
for (let i = 1; i < input.length; i++) {
result -= totalizer(input[i]);
}
console.log(result);
자바스크립트의 코드로는 다음과 같다.
'프로그래밍 > 문제풀이' 카테고리의 다른 글
[백준] 1012. 유기농 배추 (0) | 2023.12.16 |
---|---|
[백준] 1676. 팩토리얼 0의 개수 (0) | 2023.11.16 |
[코딩테스트] 백준 - 에디터 (0) | 2023.09.20 |
[코딩테스트] 2021 Dev-Matching: 웹 백엔드 개발자(상반기)다단계 - 칫솔 판매 (0) | 2023.08.17 |
[코딩테스트] 연습문제 - 무인도 여행 (0) | 2023.08.09 |