문제
https://www.acmicpc.net/problem/10989
10989번: 수 정렬하기 3
첫째 줄에 수의 개수 N(1 ≤ N ≤ 10,000,000)이 주어진다. 둘째 줄부터 N개의 줄에는 숫자가 주어진다. 이 수는 10,000보다 작거나 같은 자연수이다.
www.acmicpc.net
문제만 읽고 이거 수 정렬하기 2랑 똑같은걸? 이러면서 코드 복붙해서 제출했는데 시간초과 떴다
시간초과 난 코드
#include <iostream>
#include <algorithm>
using namespace std;
int arr[1000000];
int main(void) {
int N;
scanf("%d", &N);
for (int i = 0; i < N; i++) {
scanf("%d", &arr[i]);
}
sort(arr, arr + N);
for (int i = 0; i < N; i++) {
printf("%d\n", arr[i]);
}
}
그래서 벡터를 사용해서 다시 제출 해봤는데 메모리 초과가 났다.
메모리초과가 난 코드
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main(void) {
int N;
scanf("%d", &N);
vector<int> arr(N);
for (int i = 0; i < N; i++) {
scanf("%d", &arr[i]);
}
sort(arr.begin(), arr.end());
for (int i = 0; i < N; i++) {
printf("%d\n", arr[i]);
}
}
더 줄일 수 없을거같은데 메모리 초과가 나는게 맞나.. 싶어서 조건을 다시 살펴봤다.
N이 10,000,000 일 때 배열을 모두 int 형에 저장하려고 하면 10^7 * 4byte ≒ 10^4 * 4KB ≒ 10 * 4MB 이므로 약 40M이고 이는 메모리제한 8MB를 훨씬 초과한다.
그럼 방법이 있나.. 하다가 계수정렬(counting sort)이 생각 났다.
통과한 코드
#include <iostream>
using namespace std;
int arr[10001];
int main(void) {
int N;
scanf("%d", &N);
for (int i = 0; i < N; i++) {
int idx;
scanf("%d", &idx);
arr[idx]++;
}
for (int i = 0; i < 10001; i++) {
for (int j = 0; j < arr[i]; j++) {
printf("%d\n", i);
}
}
}
수를 입력받고 해당 인덱스의 값을 ++ 해준다. 출력은 각각의 인덱스에 저장된 횟수만큼 인덱스 i를 출력해주면 된다.
이렇게 하면 최대 인덱스가 10000이므로 메모리 사용량을 줄일 수 있고, sort 하는 과정도 생략되므로 시간초과도 해결해준다.
'개인 공부 > 코딩테스트' 카테고리의 다른 글
[C++] 백준 1193번 분수찾기 :: seoftware (0) | 2020.03.13 |
---|---|
[C++] 백준 1011번 Fly me to the Alpha Centauri :: seoftware (0) | 2020.03.07 |
[C++] 백준 2751번 수 정렬하기 2 :: seoftware (0) | 2020.03.06 |
[C++] 백준 1002번 터렛 :: seoftware (0) | 2020.03.06 |
[C++] 백준 2675번 문자열 반복 :: seoftware (0) | 2020.03.06 |
댓글