[문제풀이] 백준 2608 - 로마 숫자

kodaaa·2023년 1월 17일
0

문제풀이

목록 보기
20/23
post-thumbnail

📢 문제

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

📢 알고리즘

구현

📢 풀이

#include <iostream>
#include <map>
#include <string>

using namespace std;

map<char, int> chmp;
map<string, int> stmp;

string AraToRoman(int ara)
{
  string result;
  string rom1[4] = {"I", "X", "C", "M"}; // 1, 10, 100, 1000
  string rom4[3] = {"IV", "XL", "CD"};   // 4, 40, 400
  string rom5[3] = {"V", "L", "D"};      // 5, 50, 500
  string rom9[3] = {"IX", "XC", "CM"};   // 9, 90, 900

  string strAra = to_string(ara);
  int len = strAra.size(); // 아라비아숫자의 자리수

  // 천, 백, 십, 일의 자리로 쪼개기
  for (int i = 0, j = len - 1; i < len, j >= 0; i++, j--)
  {
    int divByI = strAra[i] - '0';
    if (divByI == 9)
    {
      result += rom9[j];
    }
    else if (divByI == 4)
    {
      result += rom4[j];
    }
    else if (divByI >= 5)
    {
      result += rom5[j]; // 5부터 처리
      if (divByI != 5)
      {
        for (int k = 5; k < divByI; k++) //나머지 처리
        {
          result += rom1[j];
        }
      }
    }
    else
    { // divByI<5
      for (int k = 0; k < divByI; k++)
      {
        result += rom1[j];
      }
    }
  }

  return result;
}

int RomanToAra(string s)
{
  int result = 0;

  for (int i = 0; i < s.size(); i++)
  {
    char now = s[i];
    if (i < s.size() - 1) // 현재가 마지막이 아닌 경우
    {
      if (chmp.find(now)->second >= chmp.find(s[i + 1])->second)
      { // 현재>=다음 이면 현재꺼 더함
        result += chmp.find(now)->second;
      }
      else
      {
        // 현재<다음 이면 두문자 한꺼번에 읽음
        string tmp;
        tmp += now;
        tmp += s[i + 1];
        result += stmp.find(tmp)->second;
        i++;
      }
    }
    else // 현재가 마지막인 경우
    {
      // 현재꺼 더함
      result += chmp.find(now)->second;
    }
  }
  return result;
}

int main()
{
  chmp.insert({'M', 1000});
  chmp.insert({'D', 500});
  chmp.insert({'C', 100});
  chmp.insert({'L', 50});
  chmp.insert({'X', 10});
  chmp.insert({'V', 5});
  chmp.insert({'I', 1});

  stmp.insert({"IV", 4});
  stmp.insert({"IX", 9});
  stmp.insert({"XL", 40});
  stmp.insert({"XC", 90});
  stmp.insert({"CD", 400});
  stmp.insert({"CM", 900});

  string i1, i2;
  int result;
  cin >> i1 >> i2;

  result = RomanToAra(i1) + RomanToAra(i2);
  cout << result << "\n"
       << AraToRoman(result);
}
  • 로마 -> 아라비아 는 비교적 쉽게 했다

    • 빠른 검색을 위해 map 사용
  • 아라비아 -> 로마가 어려웠다!

    • 아라비아숫자를 천, 백, 십, 일의 자리로 쪼개서 각각 처리해야 한다
    1. 아라비아숫자를 문자열로 변환해 전체 자릿수(길이)를 구하고
      string strAra = to_string(ara);
       int len = strAra.size(); // 아라비아숫자의 자릿수
    2. 문자열 하나하나를 가리킨 것(=1000의 자리수, 100의 자리수, ...)에 대해서 연산
      for (int i = 0, j = len - 1; i < len, j >= 0; i++, j--){
        int divByI = strAra[i] - '0';
        ...
       }
    • 1000으로 나눈 몫 = 1000의 자리수, 100으로 나눈 몫 = 100의 자리수.. 이런 식으로 int형을 직접 나눠서 그에 따른 몫을 구해도 됨. 하지만 나는 앞의 방법이 더 편했음.
  • 데이터를 저장하는 방법이 중요
    앞자리 별로 묶고, 몇의 자리냐에 따라 인덱스로 지칭 가능

    string rom1[4] = {"I", "X", "C", "M"}; // 1, 10, 100, 1000
     string rom4[3] = {"IV", "XL", "CD"};   // 4, 40, 400
     string rom5[3] = {"V", "L", "D"};      // 5, 50, 500
     string rom9[3] = {"IX", "XC", "CM"};   // 9, 90, 900

참고
https://yiyj1030.tistory.com/260
https://plzfdaylife.tistory.com/151

profile
취뽀하자(●'◡'●)💕

0개의 댓글