1431.시리얼 번호 본문
문제링크 : https://www.acmicpc.net/problem/1431
< 입력 >
기타의 개수 N(<=1,000)
N개의 줄에 시리얼 번호 (길이 최대 50, 알파벳 대문자 및 숫자로만 구성, 중복 X)
< 출력 >
시리얼 번호를 주어진 조건에 따라 정렬하여 결과를 출력
< 풀이 >
주어진 조건에 따라 정렬을 해야 하므로 가장 중요한 것은 조건이다.
위 내용이 그 조건이고 주어진 조건을 그대로 따라가면 되는 간단한 문제이다.
비교의 우선순위가 1 > 2 > 3이기 때문에 따라서 먼저 1번 조건을 확인한다.
A와 B의 길이가 다를 때, 짧은 것이 먼저 온다. 즉, strlen을 사용해서 비교를 하라는 조건이다.
다음으로 길이가 같을 때 자리수의 합(숫자인 것만)을 비교한다. 이 과정은 매번 비교할 때마다 자리수의 합을 구하면 상당히 긴 시간이 걸릴 수 있는 과정이다.
그래서 문자열을 입력받으면서 입력받은 문자열의 자리수 합을 미리 계산해서 문자열과 함께 저장한다.
자리수의 합은 0부터 strlen보다 작을 때까지 char들을 확인하여 '0'<=char<='9'일 경우 char-'0'한 값을 더하면 된다.
마지막 조건은 사전순으로 비교하는 과정이다. strcmp를 통해 쉽게 구할 수 있지만
문자열 다루는 연습을 위해 직접 구현해보면 앞자리부터 비교하며
만약 해당 자리의 문자가 다르다면 (int)로 바꿔서 비교하고 break하면 된다.
이는 숫자의 ASCII < 영어 대문자의 ASCII이기 때문에 가능하다.
정렬을 하며 이 조건들을 모두 확인했다면 출력만 하면 끝 !
- 소스 코드 -
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 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | /* * 문제에서 제시한 조건을 최대한 따라갔습니다. * for문이 길어지고 귀찮을 수 있는 자리수의 합 더하기의 경우 * 입력을 받으면서 처리해서 나온 결과와 함께 Serial이라는 구조체에 포함했습니다. * 다음으로 길이는 strlen을 활용했고 * 사전순 비교는 '0'~'9'가 'A'~'Z'보다 ASCII 상으로 작다는 점을 이용해서 구분했습니다. * 비교의 우선순위는 if - else if - else if의 우선순위를 이용해서 해결했습니다. */ #include<iostream> #include<string.h> using namespace std; struct Serial{ char str[51]; int numSum; }; int main(void){ int n; cin>>n; Serial serial[1005]; char temp[52]; int tempSum=0; for(int i=0;i<n;i++){ tempSum=0; scanf("%s",&serial[i].str); for(int j=0;j<strlen(serial[i].str);j++){ if(serial[i].str[j]>='0'&&serial[i].str[j]<='9'){ tempSum+=(int)serial[i].str[j]-(int)'0'; } } serial[i].numSum=tempSum; } for(int i=0;i<n-1;i++){ for(int j=i;j<n;j++){ bool flag=false; // 비교 1 문자열 길이 비교 if(strlen(serial[i].str)>strlen(serial[j].str)){ flag=true; }else if(strlen(serial[i].str)==strlen(serial[j].str)){ //비교 2 자리수 합 비교 if(serial[i].numSum>serial[j].numSum){ flag=true; } else if(serial[i].numSum==serial[j].numSum){ //비교 3 사전순 비교 for(int k=0;k<strlen(serial[i].str);k++){ if(serial[i].str[k]!=serial[j].str[k]){ if((int)serial[i].str[k]>(int)serial[j].str[k]){ flag=true; break; } else{ break; } } } } } if(flag){ Serial compareTemp=serial[j]; serial[j]=serial[i]; serial[i]=compareTemp; } } } for(int i=0;i<n;i++){ printf("%s\n",serial[i].str); } } | cs |
'알고리즘 문제풀기 > 백준(Acmicpc)' 카테고리의 다른 글
2004. 조합 0의 개수 (0) | 2019.01.28 |
---|---|
2870. 수학숙제 (0) | 2019.01.25 |
1309.동물원 (0) | 2019.01.22 |
11060. 점프 점프 (0) | 2019.01.18 |
10164. 격자상의 경로 (0) | 2019.01.17 |