9번 문제
내가 풀이한 답
처음에는 간단히 모든 수를 돌며 그 수에 해당하는 수까지 또 돌아서 약수를 구하는 방식으로 코드를 짰다. 즉, 모든 수를 다 돌기 때문에 N제곱의 시간복잡도가 나온다.
#include <stdio.h>
using namespace std;
int main(int argc, char** argv) {
//freopen("input.txt", "rt", stdin);
int n, i, j, cnt=0;
scanf("%d", &n);
for(i=1; i<=n; i++) {
cnt=0;
for(j=1; j<=i; j++){
if(i%j==0){
cnt++;
}
}
printf("%d ", cnt);
}
printf("\n");
}
그 결과는 60점에 큰 숫자로 들어가버리면 시간 초과가 뜬다... (Time Limit: 1초)
더 곰곰히 생각해보다가 더 이상 떠오르질 않아서 강의 초반부에서 전략을 들었다. 모든 경우의 수를 다 도는 것은 비효율적이므로 어차피 약수를 구하는 것은 배수의 개념으로도 풀 수 있다고 말하였다. 다시 머리를 한 대 얻어맞은 듯한 느낌을 받았다. 강의의 내용은 다음과 같다. 순회(for)를 돌면서 해당하는 값의 배수들만 값을 증가시켜주는 방법이다.
#include <stdio.h>
using namespace std;
int main(int argc, char** argv) {
//freopen("input.txt", "rt", stdin);
int array[50001];
int n, i, j;
scanf("%d", &n);
for(i=1; i<=n; i++) {
for(j=i; j<=n; j=j+i){
array[j]++;
}
}
for(i=1; i<=n; i++){
printf("%d ", array[i]);
}
}
그 결과 80점... 왜 그럴까.. 하고 사이트의 답안과 비교해봤다.
사이트의 답안
#include<stdio.h>
using namespace std;
int cnt[50001];
int main(){
//freopen("input.txt", "rt", stdin);
int n, i, j;
scanf("%d", &n);
for(i=1; i<=n; i++){
for(j=i; j<=n; j=j+i){
cnt[j]++;
}
}
for(i=1; i<=n; i++){
printf("%d ", cnt[i]);
}
return 0;
}
사이트의 답안과 내 코드는 배열을 선언한 부분의 전역인지 지역인지의 차이였다. 지역변수와 전역변수의 차이점에 대해 조사를 해봐야겠다...
'알고리즘 & 자료구조 > 기초 다잡기' 카테고리의 다른 글
11. 숫자의 총 개수(small) (0) | 2020.09.03 |
---|---|
10. 자릿수의 합 (0) | 2020.09.03 |
8. 올바른 괄호 (0) | 2020.09.02 |
7. 영어단어 복구 (0) | 2020.09.02 |
6. 숫자만 추출 (0) | 2020.09.01 |