C# 백준 2504 괄호의 값

2024. 2. 27. 14:50C# 백준 알고리즘

괄호의 값 

 

시간 제한메모리 제한제출정답맞힌 사람정답 비율
1 초 128 MB 60475 16638 12541 30.293%

문제

4개의 기호 ‘(’, ‘)’, ‘[’, ‘]’를 이용해서 만들어지는 괄호열 중에서 올바른 괄호열이란 다음과 같이 정의된다.

  1. 한 쌍의 괄호로만 이루어진 ‘()’와 ‘[]’는 올바른 괄호열이다.
  2. 만일 X가 올바른 괄호열이면 ‘(X)’이나 ‘[X]’도 모두 올바른 괄호열이 된다.
  3. X와 Y 모두 올바른 괄호열이라면 이들을 결합한 XY도 올바른 괄호열이 된다.

예를 들어 ‘(()[[]])’나 ‘(())[][]’ 는 올바른 괄호열이지만 ‘([)]’ 나 ‘(()()[]’ 은 모두 올바른 괄호열이 아니다. 우리는 어떤 올바른 괄호열 X에 대하여 그 괄호열의 값(괄호값)을 아래와 같이 정의하고 값(X)로 표시한다.

  1. ‘()’ 인 괄호열의 값은 2이다.
  2. ‘[]’ 인 괄호열의 값은 3이다.
  3. ‘(X)’ 의 괄호값은 2×값(X) 으로 계산된다.
  4. ‘[X]’ 의 괄호값은 3×값(X) 으로 계산된다.
  5. 올바른 괄호열 X와 Y가 결합된 XY의 괄호값은 값(XY)= 값(X)+값(Y) 로 계산된다.

예를 들어 ‘(()[[]])([])’ 의 괄호값을 구해보자. ‘()[[]]’ 의 괄호값이 2 + 3×3=11 이므로 ‘(()[[]])’의 괄호값은 2×11=22 이다. 그리고 ‘([])’의 값은 2×3=6 이므로 전체 괄호열의 값은 22 + 6 = 28 이다.

여러분이 풀어야 할 문제는 주어진 괄호열을 읽고 그 괄호값을 앞에서 정의한대로 계산하여 출력하는 것이다.

입력

첫째 줄에 괄호열을 나타내는 문자열(스트링)이 주어진다. 단 그 길이는 1 이상, 30 이하이다.

출력

첫째 줄에 그 괄호열의 값을 나타내는 정수를 출력한다. 만일 입력이 올바르지 못한 괄호열이면 반드시 0을 출력해야 한다.

 

예제 입력 1

(()[[]])([])

예제 출력 1

28

예제 입력 2

[][]((])

예제 출력 2

0

 

나의 실력을 깨달은 문제

이 문제는 스택을 이용하여 푸는 문제인데 이 문제가 어떤 답을 원하는지는 바로 알았으나 어떻게 로직을 구현할지 엄청 애먹은 문제였다.

 

그래서 어떻게 풀어야할지 1시간 정도 고민을 해도 어떻게 짜야할지 모르겠어서 푼 사람들이 로직을 어떻게 설계했는지만 보고 그걸 이용해서 풀었다.

 

코드가 엄청 더러워지고 길어져서 풀어도 찜찜함 느낌이 들고 그리고 이렇게 풀어도 바로 바로 풀린게 아니라 결국 반례를 찾아달란 질문을 하게되고 그 반례를 보고 거의 하루가 지나고 5시간만에 푼거같다.. 실버 4문제지만 역시 기본기가 부족한 나한테 엄청 애먹은 문제였고 왜 정답자가 30퍼밖에 안되는지도 알게되었다.

 

ps. 실버 4문제가 아니라 골드 5문제였다. 역시 어려운 이유가 있었다..

 

이걸 풀고 다른분의 C#코드를 봤는데 엄청 깔끔하게 짠걸 보고 진짜 아직 배워야할게 많구나 깨달았다..

 

 

 

내가 푼 코드

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Prob2504_괄호의_값
{
    class Program
    {
        static int sum;
        static void Main(string[] args)
        {
            string parenthesis = Console.ReadLine();               
            int index = 0;

            Stack<string> stack = new Stack<string>();

            while (true)
            {                            
                string current = parenthesis[index].ToString();

                if (current == ")")
                {
                    if (stack.Count == 0)
                    {
                        Console.WriteLine(0);
                        return; 
                    }
                    if (stack.Count == 1 && stack.Peek() != "(")
                    {
                        Console.WriteLine(0);
                        return;
                    }
                    
                    if (stack.Peek() == "(")
                    {
                        int number = 2;
                        stack.Pop();

                        while (stack.Count != 0)
                        {
                            if (stack.Peek() == "[" || stack.Peek() == "(")
                            {
                                stack.Push(number.ToString());
                                number = 0;
                                break;
                            }                        
                            else
                            {
                                int a = int.Parse(stack.Pop());
                                number += a;
                            }
                        }

                        if (number != 0)
                        {
                            stack.Push(number.ToString());
                        }
                    }
                    else if (stack.Peek() != "(")
                    {
                        int number = 0;

                        while (stack.Count != 0)
                        {
                            if (stack.Peek() == "[")
                            {
                                Console.WriteLine(0);
                                return;
                            }
                            else if (stack.Peek() == "(")
                            {
                                stack.Pop();
                                number *= 2;
                                stack.Push(number.ToString());
                                break;
                            }
                            else
                            {
                                int a = int.Parse(stack.Pop());
                                number += a;
                            }
                        }
                    }
                }
                else if (current == "]")
                {
                    if (stack.Count == 0)
                    {
                        Console.WriteLine(0);
                        return;
                    }

                    if (stack.Count == 1 && stack.Peek() != "[")
                    {
                        Console.WriteLine(0);
                        return;
                    }

                    if (stack.Peek() == "[")
                    {
                        int number = 3;
                        stack.Pop();
                        while (stack.Count != 0)
                        {
                            if (stack.Peek() == "[" || stack.Peek() == "(")
                            {
                                stack.Push(number.ToString());
                                number = 0;
                                break;
                            }
                            else
                            {
                                int a = int.Parse(stack.Pop());
                                number += a;
                            }
                        }

                        if (number != 0)
                        {
                            stack.Push(number.ToString());
                        }
                    }
                    else if (stack.Peek() != "[")
                    {
                        int number = 0;

                        while (stack.Count != 0)
                        {
                            if (stack.Peek() == "(")
                            {
                                Console.WriteLine(0);
                                return;
                            }
                            else if (stack.Peek() == "[")
                            {
                                stack.Pop();
                                number *= 3;
                                stack.Push(number.ToString());
                                break;
                            }
                            else
                            {
                                int a = int.Parse(stack.Pop());
                                number += a;
                            }
                        }
                    }
                }
                else
                {
                    stack.Push(parenthesis[index].ToString());
                }

                if (stack.Count != 0)
                {
                    if (stack.Peek() == ")" || stack.Peek() == "]")
                    {
                        Console.WriteLine(0);
                        return;
                    }
                }

                index++;

                if(index == parenthesis.Length)
                {
                    while (stack.Count != 0)
                    {
                        if(stack.Peek() == "(" ||
                            stack.Peek() == "[" ||
                            stack.Peek() == "]" ||
                            stack.Peek() == ")")
                        {
                            Console.WriteLine(0);
                            return;
                        }

                        sum += int.Parse(stack.Pop());
                    }
                    Console.WriteLine(sum);
                    return;
                }
            }         
        }
    }
}

'C# 백준 알고리즘' 카테고리의 다른 글

C# 백준 1916 최소비용 구하기  (0) 2024.03.12
C# 백준 14719 빗물  (0) 2024.02.29
C# 백준 1010 다리놓기  (0) 2024.02.25
C# 백준 14888 연산자 끼워넣기  (1) 2024.02.24
C# 백준 2581 소수  (1) 2024.02.24