Post

[프로그래머스] 점 찍기 with C++

🌜 프로그래머스 링크

문제 설명

좌표평면을 좋아하는 진수는 x축과 y축이 직교하는 2차원 좌표평면에 점을 찍으면서 놀고 있습니다. 진수는 두 양의 정수 k, d가 주어질 때 다음과 같이 점을 찍으려 합니다.

  • 원점(0, 0)으로부터 x축 방향으로 a*k(a = 0, 1, 2, 3 …), y축 방향으로 b*k(b = 0, 1, 2, 3 …)만큼 떨어진 위치에 점을 찍습니다.
  • 원점과 거리가 d를 넘는 위치에는 점을 찍지 않습니다.

예를 들어, k가 2, d가 4인 경우에는 (0, 0), (0, 2), (0, 4), (2, 0), (2, 2), (4, 0) 위치에 점을 찍어 총 6개의 점을 찍습니다.

정수 k와 원점과의 거리를 나타내는 정수 d가 주어졌을 때, 점이 총 몇 개 찍히는지 return 하는 solution 함수를 완성하세요.

제한사항

  • 1 ≤ k ≤ 1,000,000
  • 1 ≤ d ≤ 1,000,000

입출력 예

kdresult
246
1526

Github 링크

문제풀이

  • x,y를 분리하지말고 최대값은 어짤피 같으니깐 한개의 축으로 계산가능하다
  • sqrt를 사용하는게 더유리하다.

코드 (C++)

1
2
3
4
5
6
7
long long solution1(int k, int d) {
    long long answer = d/k + 1; //x축 위의 해당점들
    long long tempK = 1ll * d * d; //1ll은 long long 변환을 위해 곱해줌
    for (long long i = 0; i < d; i += k)
        answer += (long long)sqrt(tempK - i * i)/k;
    return answer;
}

피드백

  • 이중 포문을 사용하면 답을 구할수는있지만 시간초과 문제가 생긴다
  • 최대한 포문을 줄이는게 관건
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
long long solution(int k, int d) {
    long long answer = 0;
    int maxMultiply = d / k;
    long long maxVal = 1ll * d * d;
    long long tempK = 1ll * k * k;
    for (long long i = 0; i <= maxMultiply; ++i)
    {
        long long poweri = i*i;
        for (long long j = 0; j <= maxMultiply; ++j)
        {
            if (d < sqrt(tempK * poweri + tempK * j*j))
                break;
            else
                answer++;
        }
    }
    return answer;
}

This post is licensed under CC BY 4.0 by the author.