#include <string>
#include <vector>
using namespace std;
int solution(int n) {
int answer = 0;
for(int i=1; i<=n; i++){
for(int j=1; j<=n; j++){
if(i*j==n) answer++;
}
}
return answer;
}
그동안 Lv 0. 문제들을 풀면서 시간제한이나 공간제한이 명시되어있는 부분이 없어서 그냥 이렇게 이중for문으로 짜서 제출하니까,
이런 결과물을 얻을 수 있었다.
테스트 1 〉 통과 (0.01ms, 4.01MB)
테스트 2 〉 통과 (0.01ms, 3.59MB)
테스트 3 〉 통과 (3056.71ms, 4.21MB)
테스트 4 〉 통과 (0.01ms, 4.21MB)
테스트 5 〉 실패 (2850.53ms, 4.13MB)
테스트 6 〉 실패 (시간 초과)
테스트 7 〉 통과 (0.01ms, 3.68MB)
테스트 8 〉 통과 (0.01ms, 4.14MB)
테스트 9 〉 실패 (시간 초과)
테스트 10 〉 실패 (시간 초과)
그래서 시간복잡도를 줄이기 위해서 두번째로 작성한 풀이는,
#include <string>
#include <vector>
using namespace std;
int solution(int n) {
int answer = 0;
for(int i=1; i<=n; i++){
if(n%i==0) answer++;
}
return answer;
}
이와 같다.
테스트 1 〉 통과 (0.01ms, 4.13MB)
테스트 2 〉 통과 (0.01ms, 4.16MB)
테스트 3 〉 통과 (0.37ms, 4.18MB)
테스트 4 〉 통과 (0.01ms, 4.15MB)
테스트 5 〉 통과 (0.24ms, 4.23MB)
테스트 6 〉 통과 (2.39ms, 4.14MB)
테스트 7 〉 통과 (0.01ms, 4.22MB)
테스트 8 〉 통과 (0.01ms, 4.02MB)
테스트 9 〉 통과 (2.30ms, 4.19MB)
테스트 10 〉 통과 (2.49ms, 3.63MB)
그리고 이런 문제의 경우는 두 수의 곱으로 값을 나타낼때, 대칭을 이루는 형태로 수들이 나타나니까, 그걸 이용해서 더욱 줄일 수 있다는 생각이 들었고, 다른 사람의 풀이를 보다보니 내가 생각한 것처럼 대칭성을 이용해서 풀이한 풀이를 찾을 수 있었고, 그 풀이의 경우는,
#include <string>
#include <vector>
#include <cmath>
using namespace std;
int solution(int n) {
int answer = 0;
for(int i = 1; i <= sqrt(n); i++)
{
if(n % i == 0) answer += 2;
if(i * i == n) answer--;
}
return answer;
}
이와 같았다.
만약 내가 이런 형태로 푼다면 여기서 sqrt(n); 을 사용해서 for문의 범위를 나타내었고, 그러기 위해 <cmath> 헤더까지 붙였는데,
그렇게 하기보다는
for(int i=1; i*i<=n; i++) 로 작성하는것이 더 좋을것 같다는 생각이 들었다. 그렇게 해보면,
#include <string>
#include <vector>
using namespace std;
int solution(int n) {
int answer = 0;
for(int i = 1; i*i<=n; i++)
{
if(n % i == 0) answer += 2;
if(i * i == n) answer--;
}
return answer;
}
이렇게 작성할 수 있을 것이다.
이 코드를 제출해보면,
테스트 1 〉 통과 (0.01ms, 4.16MB)
테스트 2 〉 통과 (0.01ms, 4.15MB)
테스트 3 〉 통과 (0.01ms, 4.16MB)
테스트 4 〉 통과 (0.01ms, 4.23MB)
테스트 5 〉 통과 (0.02ms, 3.63MB)
테스트 6 〉 통과 (0.01ms, 4.04MB)
테스트 7 〉 통과 (0.01ms, 4.03MB)
테스트 8 〉 통과 (0.01ms, 4.15MB)
테스트 9 〉 통과 (0.01ms, 4.16MB)
테스트 10 〉 통과 (0.01ms, 4.17MB)
이와 같은 결과를 얻을 수 있고, 가장 처음에 작성한 풀이와 비교를 해본다면,
이렇게 아주 큰 차이를 만들어내는걸 볼 수 있다.
얼핏보면 간단하게 풀이하고 넘길만한 문제겠지만,
for(int i = 1; i*i<=n; i++)
{
if(n % i == 0) answer += 2;
if(i * i == n) answer--;
}
와 같은 형태의 코드를 통해서 아주아주 커다란 차이를 만들어낼 수 있는 형태의 문제였다. 이런 생각이 나중에 소수판별할때, 에라토스테네스의 체를 활용할때 등에서 다시 사용될것이고, 그 차이가 아주아주 큰 차이를 만들어내니까 이런 사고를 할 수 있는 습관을 들이도록 하자.
그리고 위의 풀이를 잘 기억해놓고 다음에는 처음으로 이런식의 풀이로 바로 진입할 수 있도록 만들자.
'알고리즘 > 프로그래머스' 카테고리의 다른 글
Lv 0. 개미 군단 (0) | 2023.09.19 |
---|---|
Lv 0. 외계행성의 나이 - 숫자를 string으로 바꾸고 싶으면? to_string() (0) | 2023.09.18 |
Lv 0. 진료순서 정하기 - sort는 algorithm 헤더에, greater<>()는 내림차순. *다시 풀어보기* (0) | 2023.09.18 |
Lv 0. 배열 자르기 || vector의 emplace_back()과 push_back()에 대하여. (0) | 2023.09.17 |
Lv 0. 짝수의 합 (0) | 2023.09.16 |