2024. 10. 24. 19:53ㆍIT/BaekJoon
문제 링크
https://www.acmicpc.net/problem/1755
문제
79를 영어로 읽되 숫자 단위로 하나씩 읽는다면 "seven nine"이 된다. 80은 마찬가지로 "eight zero"라고 읽는다. 79는 80보다 작지만, 영어로 숫자 하나씩 읽는다면 "eight zero"가 "seven nine"보다 사전순으로 먼저 온다.
문제는 정수 M, N(1 ≤ M ≤ N ≤ 99)이 주어지면 M 이상 N 이하의 정수를 숫자 하나씩 읽었을 때를 기준으로 사전순으로 정렬하여 출력하는 것이다.
입력
첫째 줄에 M과 N이 주어진다.
출력
M 이상 N 이하의 정수를 문제 조건에 맞게 정렬하여 한 줄에 10개씩 출력한다.
![](https://blog.kakaocdn.net/dn/buHiXy/btsKimLwUbZ/ZulAzo4UaO8lAg2afkO4OK/img.png)
통과한 답안
using System.Text;
namespace _1755
{
internal class Program
{
static void Main(string[] args)
{
string[] inputs = Console.ReadLine().Split(' ');
int M = int.Parse(inputs[0]);
int N = int.Parse(inputs[1]);
Dictionary<string, int> dict = new Dictionary<string, int>();
for (int i = M; i <= N; i++)
{
string numberAlp = NumToAlp(i);
dict.Add(numberAlp, i);
}
var orderedNumbers = dict.OrderBy(x => x.Key).Select(x => x.Value).ToList();
for (int i = 0; i < orderedNumbers.Count; i+= 10)
{
Console.WriteLine(string.Join(" ", orderedNumbers.Skip(i).Take(10)));
}
}
static string NumToAlp(int n)
{
StringBuilder sb = new StringBuilder();
int ten = n / 10;
int rest = n % 10;
if (ten != 0)
{
sb.Append(MakeAlp(ten));
}
sb.Append(MakeAlp(rest));
return sb.ToString();
}
static string MakeAlp(int n)
{
switch (n)
{
case 0: return "zero";
case 1: return "one";
case 2: return "two";
case 3: return "three";
case 4: return "four";
case 5: return "five";
case 6: return "six";
case 7: return "seven";
case 8: return "eight";
case 9: return "nine";
default: return n.ToString();
}
}
}
}
두 숫자 M, N이 주어지는 경우, M이상 N이하의 정수들을 정렬하는 문제이다.
단 정렬의 조건이 각 숫자를 하나씩 읽은 후에, 사전 순으로 정렬하는 것이다.
문제의 예에서 알려준 것처럼 79는 'seventy nine'이 아니라 'seven nine'이 된다.
문제를 해결하기 위해서 숫자와 문자를 동시에 가질 수 있는 자료 구조인 딕셔너리를 이용하여
해당하는 정수와 그 정수를 알파벳으로 변환한 값을 저장하였다.
그 후에 LINQ를 이용하여 알파벳 순으로 정렬한 결과의 정수를 저장하는 리스트만들고,
그 리스트에 존재하는 원소들을 10개씩 잘라서 한 줄 씩 출력하도록 구현하였다.
주어진 정수를 알파벳으로 변환하는 두 메서드 MakeAlp와 NumToAlp를 이용하였는데,
원래는 NumToAlp의 메서드 하나에 구현되었던 코드였는데
switch문을 이용한 숫자 -> 알파벳의 구현 부분에서 복잡성이 느껴져서 하나의 메서드로 빼게 되었다.
이 과정을 거치면서 좋은 코드(누구라도 알아보기 용이한 코드)의 가치를 생각해볼 수 있었다.
또, LINQ를 많이 사용하였는데, 숫자를 알파벳으로 변환하고 그 값들을 저장한 뒤에
그 값들에 따라서 정렬한 숫자를 다시 가져오는 방법을 고민하다가
딕셔너리를 통해서 두 값을 동시에 저장하는 방법을 고안했고,
그 두 값을 이용하여 정렬하는 방법(OrderBy(x => x.Key).Select(x => x.Value))을 떠올릴 수 있었다.
또, 출력하는 과정에서 10개를 한 줄로 만들어야되는 조건이 있었기에
string.Join을 이용하는 과정에서 Skip(i).Take(10)을 이용하여 10개씩 나눠서 출력할 수 있었다.
이전부터 LINQ가 매우 편리하고 유용한 기능이라고 알고 있었지만, 다시금 깨달을 수 있었다.
'IT > BaekJoon' 카테고리의 다른 글
[BAEKJOON] 백준 15751: Teleportation (C#) (1) | 2024.10.29 |
---|---|
[BAEKJOON] 백준 29730: 임스의 데일리 인증 스터디 (C#) (0) | 2024.10.25 |
[BAEKJOON] 백준 14843: 정보갓 영훈이 (C#) (0) | 2024.10.24 |
[BAEKJOON] 백준 15820: 맞았는데 왜 틀리죠? (C#) (2) | 2024.10.22 |
[BAEKJOON] 백준 12971: 숫자 놀이 (C#) (0) | 2024.10.17 |