작성일 :

문제 링크

1431번 - 시리얼 번호

설명

여러 개의 문자열로 구성된 시리얼 번호가 주어졌을 때, 특정한 기준에 따라 정렬하는 문제입니다.

시리얼 번호는 알파벳 대문자와 숫자로 구성되며, 정렬 기준은 다음과 같습니다:

  • 길이가 짧은 시리얼 번호가 먼저 옵니다.
  • 길이가 같다면, 숫자만을 추출하여 그 합이 작은 시리얼 번호가 먼저 옵니다.
  • 위 두 기준이 같다면, 사전 순서대로 정렬합니다. 이때 숫자는 알파벳보다 사전상으로 작게 취급합니다.


접근법

  • 시리얼 번호를 하나씩 입력받아 저장합니다.
  • 비교 기준은 다음 순서로 적용합니다:
    1. 문자열의 전체 길이
    2. 문자열 내 숫자의 총합
    3. 사전 순서 비교
  • 비교 기준을 만족하는 정렬 함수를 구현하여 정렬을 수행합니다.



Code

C#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using System;
using System.Linq;

class Program {
  static int SumDigits(string s) {
    return s.Where(char.IsDigit).Sum(c => c - '0');
  }

  static void Main() {
    int n = int.Parse(Console.ReadLine());
    var arr = new string[n];
    for (int i = 0; i < n; i++)
      arr[i] = Console.ReadLine();

    Array.Sort(arr, (a, b) => {
      if (a.Length != b.Length)
        return a.Length - b.Length;
      int sa = SumDigits(a), sb = SumDigits(b);
      if (sa != sb) return sa - sb;
      return string.Compare(a, b, StringComparison.Ordinal);
    });

    foreach (var s in arr)
      Console.WriteLine(s);
  }
}


C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <bits/stdc++.h>
using namespace std;
typedef vector<string> vs;

bool isNum(char c) {
  return isdigit(c);
}

bool comp(const string& s1, const string& s2) {
  if (s1.size() != s2.size()) return s1.size() < s2.size();
  int sum1 = 0, sum2 = 0;
  for (size_t i = 0; i < s1.size(); i++) {
    if (isNum(s1[i])) sum1 += s1[i] - '0';
    if (isNum(s2[i])) sum2 += s2[i] - '0';
  }
  return sum1 != sum2 ? sum1 < sum2 : s1 < s2;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  int n; cin >> n;
  vs a(n);
  for (int i = 0; i < n; i++)
    cin >> a[i];

  sort(a.begin(), a.end(), comp);

  for (const auto& s : a)
    cout << s << "\n";

  return 0;
}