C언어/BAEKJOON

[백준] 10814. 나이순 정렬

너굴맨이해치움 2022. 5. 21. 03:15

: solved.ac class 2 - silver 5

 

https://www.acmicpc.net/problem/10814

 

10814번: 나이순 정렬

온라인 저지에 가입한 사람들의 나이와 이름이 가입한 순서대로 주어진다. 이때, 회원들을 나이가 증가하는 순으로, 나이가 같으면 먼저 가입한 사람이 앞에 오는 순서로 정렬하는 프로그램을

www.acmicpc.net

 

 

예제 입력

3
21 Junkyu
21 Dohyun
20 Sunyoung

예제 출력

20 Sunyoung
21 Junkyu
21 Dohyun

 

정답

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

typedef struct { 
	int age; 
	char name[101]; 
	int order; 
}member;

//비교 함수
int compare(const void* a, const void* b) {
	member* m1 = (member*)a;
	member* m2 = (member*)b;

	if (m1->age < m2->age) return -1;
	else if (m1->age > m2->age) return 1;
	else {
		if (m1->order < m2->order) return -1;
		else return 1;
	}

	return 0;
}

int main() {
	int n;
	member* list;

	scanf("%d", &n);
	list = (member*)malloc(n * sizeof(member));

	for (int i = 0; i < n; i++) {
		scanf("%d %s", &list[i].age, &list[i].name);
		list[i].order = i; 
	}

	qsort(list, n, sizeof(member), compare); 

	for (int i = 0; i < n; i++) {
		printf("%d %s\n", list[i].age, list[i].name);
	}

	return 0;
}


해설

 

: 정렬 시 비교해야 할 대상이 여럿이므로, 구조체와 수정된 compare 함수를 이용하도록 한다.

 

 

1. 회원 정보를 담는 구조체를 만든다. 나이와 가입 순서, 이름을 담는 필드를 선언해 준다.

이름 필드는 '내용이' 최대 100자까지인 것이기 때문에 널 문자가 들어갈 공간을 생각하여 101 인덱스로 선언하도록 한다.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

typedef struct { //회원의 정보를 담는 구조체
	int age; //나이
	char name[101]; //이름
	int order; //가입 순서
}member;

 

 

2. 비교 함수를 작성한다. 비교 조건이 2가지이기 때문에 compare 함수도 일반적인 형태에서 수정해야 한다.

먼저 나이 필드에 접근하여 대소를 비교하고,

만약 나이가 같다면 가입 순서 필드를 비교한다.

모든 조건이 같다면 위의 if문 중 걸리는 것이 없이 마지막 줄까지 오게 될 것이므로 0을 리턴해 주도록 한다.

//비교 함수
int compare(const void* a, const void* b) {
	member* m1 = (member*)a;
	member* m2 = (member*)b;

	if (m1->age < m2->age) return -1;
	else if (m1->age > m2->age) return 1;
	//먼저 나이의 대소를 비교
	else {
		if (m1->order < m2->order) return -1;
		else return 1;
		//나이가 같다면 가입 순서를 비교
	}

	return 0;
	//모든 조건이 같다면 0 리턴
}

 

3. 앞서 풀었던 문제와 마찬가지로 멤버 배열을 선언하고, 동적 할당으로 공간을 할당해 준다.

나이와 이름을 받으면서 가입된 순서 또한 입력받고, 나이가 같은 멤버끼리는 이 순번을 통해 비교할 수 있도록 한다.

정렬 후, 정렬된 대로 출력까지 하면 문제가 해결된다.

int main() {
	int n;
	member* list; //멤버 배열 선언

	scanf("%d", &n);
	list = (member*)malloc(n * sizeof(member));
	//멤버 배열에 공간 할당

	for (int i = 0; i < n; i++) {
		scanf("%d %s", &list[i].age, &list[i].name);
		list[i].order = i; //가입 순서 = 입력된 순서
	}

	qsort(list, n, sizeof(member), compare); //퀵 정렬

	for (int i = 0; i < n; i++) {
		printf("%d %s\n", list[i].age, list[i].name);
	}

	return 0;
}