티스토리 뷰

728x90
반응형

백준 온라인 저지(BOJ) 10814번 나이순 정렬

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

 

10814번: 나이순 정렬

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

www.acmicpc.net

* 사용언어 : C언어, C++

 

1. 문제

온라인 저지에 가입한 사람들의 나이, 이름이 가입 순으로 주어짐

① 나이가 증가하는 순으로, ② 나이가 같으면 먼저 가입한 순으로 정렬하여 출력

 

2. 풀이

주어진 순서를 유지하면서 나이로만 정렬해야하기 때문에

stable sort 를 사용해야 합니다.

 

stable sort 란 정렬 조건이 같은 경우 (이 문제의 경우 나이)

기존 순서를 유지하는 정렬 방식을 말합니다.

저는 stable sort 중 하나인 merge sort 로 구현을 해봤습니다.

 

우선 나이와 문자열을 동시에 저장하기 위해 구조체를 생성했습니다.

그리고 해당 구조체에 나이와 이름을 모두 넣은 후 merge sort 를 한 뒤 출력하였습니다.

 

위와 같은 방식으로 충분히 정답이 되었으나 아래와 같은 2가지 비효율이 발생하였습니다.

 

1) 시간 비효율

  - 구조체를 선언하여 나이와 문자열을 함께 보관함

  - 따라서 정렬 시 나이와 문자열을 모두 복사해야 함

2) 공간 비효율

  - merge sort 는 inplace sort 가 아님

  - 따라서 나이, 문자열을 가지는 구조체 배열을 하나 더 만들어야 함

 

 

위 문제들을 해결하기 위해 구조체의 주소(포인터) 배열을 사용하기로 했습니다.

이로 인해 temp 배열도 포인터로 선언할 수 있게 되어 비효율 문제를 모두 해결할 수 있었습니다.

 

나머지 풀이는 아래 소스 코드로 대체하겠습니다.

 

3. 코드

#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif
/*
10814_나이순 정렬
22988KB	68ms
*/
#include <cstdio>

const int LM = 100000;
const int CLM = 201;
int n;

struct _p {
	int age;
	char name[CLM];
} P[LM];

_p *p[LM], *t[LM];

void mSort(int s, int e) {
	if (s >= e) return;

	int m = (s + e) / 2;
	mSort(s, m);
	mSort(m + 1, e);

	int i = s, j = m + 1, k = s;
	while (i <= m && j <= e) {
		if (p[i]->age <= p[j]->age) t[k++] = p[i++];
		else t[k++] = p[j++];
	}

	while (i <= m) t[k++] = p[i++];
	while (j <= e) t[k++] = p[j++];

	for (i = s; i <= e; ++i) p[i] = t[i];
}

int main() {
#ifdef _WIN32
	freopen("input.txt", "r", stdin);
#endif // _WIN32
	scanf("%d", &n);
	for (int i = 0; i < n; ++i) {
		scanf("%d %s", &P[i].age, P[i].name);
		p[i] = &P[i];
	}

	mSort(0, n - 1);

	for (int i = 0; i < n; ++i) printf("%d %s\n", p[i]->age, p[i]->name);
	return 0;
}

 

728x90
반응형
댓글