# 본인 풀이

#include<bits/stdc++.h>
using namespace std;
int n;
string s[100];
vector<string> ret;
vector<string> result;

bool cmp(string a, string b){
    if(a.size() == b.size()){
        for (int i = 0; i < a.size(); i++){
            if((int)a[i] != (int)b[i]){
                return (int)a[i] < (int)b[i];
            }
            continue;
        }

        // 그냥 삽입해둔 코드
        return a.size() < b.size();
    }
    // 자릿수가 더 많은 문자열이 더 큰값
    return a.size() < b.size();
}

// 반례?
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    cin >> n;

    // 앞자리 0으로 시작하는 애들은 atoi 호출시 자동으로 생략해줌.
    for (int i = 0; i < n; i++){
        cin >> s[i];

        string t = "";

        // s[i] 내에 간격을 두고 숫자가 두번 등장하는 경우?
        int gap;
        for (char chr : s[i]){
            // 소문자 a ~ z 사이의 문자가 아니라면 무조건 숫자이므로 t에 푸시
            if(gap > 1){
                if(t.size()){
                    ret.push_back(t);
                    t = "";
                    gap = 0;
                }
            }
            if ((int)chr < 97 || (int)chr > 122)
            {
                t += chr;
                gap = 0;
            }
            gap++;
        }
        if(t.size()){
            ret.push_back(t);
        }
    }
    // 정렬은?
    // sort(ret.begin(), ret.end());
    for(string str : ret){
        int idx = -1;
        for (int i = 0; i < str.size(); i++){
            if(str[i] != '0'){
                break;
            }
            idx = i;
        }

        // 앞에 삽입된 0들 삭제
        if(idx != -1){
            str.erase(0, idx + 1);
            if(str.size() == 0){
                str = "0";
            }
        }
        result.push_back(str);
    }
    sort(result.begin(), result.end(), cmp);
    for(string str: result){
        cout << str << "\n";
    }

    return 0;
}

문자를 숫자로 파싱할때 주의점

int형 등으로 문자열을 파싱하게 되는데, 이때 문자열 길이에 주의해야한다. 문제 조건이 100글자까지 파싱 가능하도록 하였기때문에, 매우 큰 데이터를 다루는 자료형을 사용하지 않는 이상 문제는 오답처리됨!

  1. ret벡터에 각 입력되는 문자열들 중 숫자로 분리 가능한 부분을 추출하여 저장
  2. result에 각 숫자들을 순회하며 000..12와 같이 앞자리가 0으로 시작하는 데이터들은 순수 숫자로 수정
  3. sort 메서드에 분류기준 함수를 커스텀하여 cmp에 구현. 문자열 길이가 더 길다는 의미는 자릿수가 많다는 의미이므로 -> 반드시 더 큼
  4. 문자열 사이즈가 동일한 경우 각 자리를 순회하며 더 큰 값을 리턴

# 모범 답안

#include<bits/stdc++.h>
using namespace std;
int n;
vector<string> v;
string s, ret;

void go(){
    while(true){
        // 0지우기
        if(ret.size() && ret.front() == '0'){
            ret.erase(ret.begin());
        }else{
            break;
        }
    }

    // 다 지워버렸으면 해당 문자열은 0 -> 내 로직에도 포함되어 있음
    if(ret.size() == 0){
        ret = "0";
    }
    v.push_back(ret);
    ret = "";
}

bool cmp(string a, string b){
    // 사이즈 동일하면 -> 아스키코드 총합
    if(a.size() == b.size()){
        return a < b;
    }

    // 사이즈 다르면 -> 사이즈 큰애 리턴
    return a.size() < b.size();
}

// 반례?
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    cin >> n;
    for (int i = 0; i < n; i++){
        cin >> s;
        ret = "";
        for (int j = 0; j < s.size(); j++){
            // 숫자들은 아스키코드 65밑에 깔려있음. 나머지 범위는 고려할 필요 X
            // 숫자가 아닌 문자가 나타난 경우 -> 정제하러 go함수로 이동
            if(s[j] < 65){
                ret += s[j];
            }else if(ret.size()){
                go();
            }
        }
        if(ret.size()){
            go();
        }
    }

    sort(v.begin(), v.end(), cmp);
    for(string i: v){
        cout << i << "\n";
    }
    return 0;
}
  1. 반례 고려는 잘 되었음.
  2. cmp 구현도 굿
  3. 사이즈 비교는 문자열 사전순 비교가 가능하므로 굳이 한글자씩 순회하며 int로 바꿔줄 필요가 없음!