문제
온라인 저지에 가입한 사람들의 나이와 이름이 가입한 순서대로 주어진다. 이때, 회원들을 나이가 증가하는 순으로, 나이가 같으면 먼저 가입한 사람이 앞에 오는 순서로 정렬하는 프로그램을 작성하시오.
입력
첫째 줄에 온라인 저지 회원의 수 N이 주어진다. (1 ≤ N ≤ 100,000)
둘째 줄부터 N개의 줄에는 각 회원의 나이와 이름이 공백으로 구분되어 주어진다. 나이는 1보다 크거나 같으며, 200보다 작거나 같은 정수이고, 이름은 알파벳 대소문자로 이루어져 있고, 길이가 100보다 작거나 같은 문자열이다. 입력은 가입한 순서로 주어진다.
출력
첫째 줄부터 총 N개의 줄에 걸쳐 온라인 저지 회원을 나이 순, 나이가 같으면 가입한 순으로 한 줄에 한 명씩 나이와 이름을 공백으로 구분해 출력한다.
구상
두 가지 정보를 입력받아서 한꺼번에 정렬해야 하므로 정보를 구조체로 묶어서 정렬한다.
struct info{
int age;
char name[101];
};
나이와 이름 정보를 받을 수 있는 구조체를 선언한다. 이름은 100자리까지인데 null문자를 포함할 공간이 있어야 하므로 크기를 101로 한다.
int n;
scanf("%d", &n);
info* p_info = (info*)malloc(sizeof(info) * n);
for (int i = 0; i < n; i++) {
scanf("%d%*c%s", &p_info[i].age, p_info[i].name);
}
크기를 입력받고 해당 크기의 구조체 배열을 동적할당한다.
%d 다음에 있는 %*c는 %s로 문자열을 입력받기 위한 준비다.
%d로 수를 입력받고 공백이나 엔터를 입력하면 버퍼에 남게 되는데 곧바로 문자를 입력받게 되면 버퍼에 있던 공백이 입력되어 원하는 결과를 얻지 못할 수 있다.
%c는 문자를 입력하라는 뜻인데, *이 붙으면 그 문자를 입력받되 무시하라는 뜻이다.
버퍼를 비울 때 fflush(stdin)을 사용하면 된다는 참고서적들이 꽤 있는데, 표준이 아닌데다 코드가 길어진다. scanf 형식문자열을 이용하면 한 줄에 수와 문자열을 받을 수 있다.
int compare(const void* arg1, const void* arg2) {
info *a = (info*)arg1; //void를 int형으로 변환
info *b = (info*)arg2;
//오름차순 정렬
if (a->age > b->age) return 1;
else if (a->age < b->age) return -1;
else return 0;
}
구조체를 qsort로 정렬하는 방법은 배열을 정렬할 때와 다르지 않다. 자료형을 구조체로 주고, 어떤 구조체 멤버를 기준으로 정렬할 건지만 정해서 알려주면 된다. 문제에서는 나이순으로 정렬하라 했으니 정수 필드를 기준으로 정렬한다.
나이가 같을 때는 정렬하지 않으므로 등록한 순서 그대로 남아 있는다.
코드
#include <stdio.h>
#include <stdlib.h>
struct info{ //정보가 있는 구조체
int age;
char name[101];
};
int compare(const void* arg1, const void* arg2) { //정렬
info *a = (info*)arg1; //void를 int형으로 변환
info *b = (info*)arg2;
//오름차순 정렬
if (a->age > b->age) return 1;
else if (a->age < b->age) return -1;
else return 0;
}
int main(void)
{
int n;
scanf("%d", &n);
info* p_info = (info*)malloc(sizeof(info) * n);
for (int i = 0; i < n; i++) { //입력
scanf("%d%*c%s", &p_info[i].age, p_info[i].name);
}
qsort(p_info, n, sizeof(info), compare); //나이 순 정렬
for (int i = 0; i < n; i++) { //출력
printf("%d %s\n", p_info[i].age, p_info[i].name);
}
free(p_info); //할당 해제
return 0;
}
'프로그래밍 > Baekjoon' 카테고리의 다른 글
[C++] 백준 11650. 좌표 정렬하기 (0) | 2022.11.18 |
---|---|
[C++] 백준 10816. 숫자 카드 2 (0) | 2022.11.13 |
[C언어] 백준 9012. 괄호 (0) | 2022.11.09 |
[C언어] 백준 1920. 수 찾기 (0) | 2022.11.04 |
[C언어] 백준 1259. 팰린드롬수 (0) | 2022.11.03 |