PS_Baekjoon
[백준 C++] 1431번 : 시리얼 번호
SMILELY
2023. 3. 21. 12:09
https://www.acmicpc.net/problem/1431
1431번: 시리얼 번호
첫째 줄에 기타의 개수 N이 주어진다. N은 50보다 작거나 같다. 둘째 줄부터 N개의 줄에 시리얼 번호가 하나씩 주어진다. 시리얼 번호의 길이는 최대 50이고, 알파벳 대문자 또는 숫자로만 이루어
www.acmicpc.net
풀이 :
- 문제에서 요구하는 그대로 정렬을 하면 된다
1. a와 b 중 길이가 더 짧은 것이 먼저
2. 길이가 같다면 숫자만 더해서 더 작은 숫자의 합인 것이 먼저
3. 숫자의 합도 같다면 사전순으로 더 작은 것이 먼저
- 출력 예시
5
AAAAAAA90 //길어서 제일 뒤로
AAAA90 //9+0 = 9
AAAA89 //8+9 = 17
A90AAA //9+0 = 9 -> 두번째 단어와 숫자의 합이 같지만 숫자의 위치가 앞서기 때문에 사전순으로 더 작다
AAAAAA //숫자가 없기 때문에 사전순으로 가장 작다
answer :
AAAAAA
A90AAA
AAAA90
AAAA89
AAAAAAA90
- 코드 작성시 주의해야할 점은 숫자의 합을 구할 때 '0'을 빼줘야 한다는 점이다.
어차피 아스키코드라서 뺄 필요가 없지 않나하고 생각하고 코드를 작성했는데, 예제 출력은 잘 되지만 백준에서는 틀렸다.
코드 :
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main(){
cin.tie(NULL);
ios::sync_with_stdio(false);
int n, cnta,cntb;
string s[55];
cin >> n;
for(int i=0; i<n; i++){
cin >> s[i];
}
for(int i=0; i<n; i++){
for(int j=i+1; j<n; j++){
if(s[i].size() > s[j].size()){ //a단어의 길이가 더 길다면 swap
swap(s[i],s[j]);
}else if(s[i].size() == s[j].size()){ //길이가 같다면
cnta = cntb = 0; //자리수의 합을 저장할 변수 0으로 초기화
for(int k=0; k<s[i].size(); k++){ //단어의 길이만큼 돌면서
if(s[i][k] >= '0' && s[i][k] <= '9'){ //숫자가 나오면 합을 저장한다
cnta += s[i][k]-'0';
}
if(s[j][k] >= '0' && s[j][k] <= '9'){
cntb += s[j][k]-'0';
}
}
if(cnta > cntb){ //a 단어에 있는 숫자의 합이 b 단어에 있는 숫자의 합보다 크면 swap
swap(s[i],s[j]);
}else if(cnta == cntb){ //둘의 숫자의 합이 같다면
if(s[i] > s[j]){ //사전순으로 b가 더 작다면 swap
swap(s[i],s[j]);
}
}
}
}
}
for(int i=0; i<n; i++){
cout << s[i] << '\n';
}
}