Coding Test/programmers

[프로그래머스] 교점에 별 만들기 c++

owls 2022. 9. 29. 14:58
728x90

문제 설명

Ax + By + C = 0 형태로 되어 있는 n개의 직선이 (A, B, C) 로 2차원 벡터로 데이터를 제공한다.

n개의 직선들의 교점 중 정수로만 이루어진 교점을 찾고,

교점에는 "*" 별 모양으로 표시하고 나머지 좌표는 "."으로 채운다.

격자판은 무한히 넓으니 모든 별을 포함하는 최소한의 크기만 나타낸다.

 

※참고 사항

Ax + By + E = 0

Cx + Dy + F = 0

두 직선의 교점이 유일하게 존재할 경우, 그 교점은 다음과 같습니다.

또, AD - EC = 0 인 경우 두 직선은 평행 또는 일치합니다.

제한 사항

  • line의 세로(행) 길이는 2 이상 1,000 이하인 자연수입니다.
    • line의 가로(열) 길이는 3입니다.
    • line의 각 원소는 [A, B, C] 형태입니다.
    • A, B, C는 -100,000 이상 100,000 이하인 정수입니다.
    • 무수히 많은 교점이 생기는 직선 쌍은 주어지지 않습니다.
    • A = 0이면서 B = 0인 경우는 주어지지 않습니다.
  • 정답은 1,000 * 1,000 크기 이내에서 표현됩니다.
  • 별이 한 개 이상 그려지는 입력만 주어집니다.

입출력 예

line result
[[2, -1, 4], [-2, -1, 4], [0, -1, 1], [5, -8, -12], [5, 8, 12]] ["....*....", ".........", ".........", "*.......*", ".........", ".........", ".........", ".........", "*.......*"]
[[0, 1, -1], [1, 0, -1], [1, 0, 1]] ["*.*"]
[[1, -1, 0], [2, -1, 0]] ["*"]
[[1, -1, 0], [2, -1, 0], [4, -1, 0]] ["*"]

풀이

문제에서 교점을 찾기 위해 필요한 수식이 주어졌다.

식을 사용해서 교점을 찾아야 한다.

 

1. 직선 2개씩을 비교하여 교점 계산을 한다.(위 식을 사용해서 교점 계산)

2. "AD - BC = 0" 가 나온다면,  평행 또는 일치하는 경우이므로 두 직선은 교점이 없다. 다음 직선과 비교를 진행한다.

3.  (BF - ED) % (AD - EC) 나머지가 0이 아닐 경우, 정수가 아니므로 다음 직선과 비교를 진행한다.

     (EC - AF) % (AD - EC) 도 동일하게 검사한다.

4. 교점 x, y를 구하고 벡터에 저장한다.

5. x , y의 최소값과 최댓값을 저장한다. (격자판에 나타내기 위한 최소한의 크기를 위해)

6. 격자판의 크기를 계산한다. (x는 행, y는 열)

    행 크기는  " x최댓값 - x최소값 + 1 " 이다. (0포함하기 위해 +1한다.)

    열 크기는 " y최댓값 - y최소값 + 1 "

7. 정확한 좌표 값을 찾는 문제가 아니다.

    ".", "*" 문자로 거리를 표현하기만 하면 된다.

    x는 작은 값, y는 큰 값 부터 적용되어야 한다.

    print는 파란색 동그라미 부터 시작되니까!! 

   (이 부분이 이해가 안갔는데 계속 고민하다가 떠올랐다. 후,,,)    

#include <string>
#include <vector>
#include <algorithm>
#include <climits>

using namespace std;

vector<string> solution(vector<vector<int>> line) {
    
    long long minX = LLONG_MAX, minY = LLONG_MAX;
    long long maxX = LLONG_MIN, maxY = LLONG_MIN;
    
    vector<pair<long long, long long>> coords;
    int lineSize = line.size();
    for(int i = 0; i < lineSize; i++){
        for(int j = i + 1; j < lineSize; j++){
            long long A = line[i][0], B = line[i][1], E = line[i][2];
            long long C = line[j][0], D = line[j][1], F = line[j][2];
            
            long long xNumberator = B * F * 1LL - E * D * 1LL;
            long long yNumberator = E * C * 1LL - A * F * 1LL;
            
            long long mod = A * D * 1LL - B * C * 1LL;
            
            if(mod == 0){
                continue;
            }
            
            if(xNumberator % mod || yNumberator % mod){
                continue;
            }
            
            long long x = xNumberator / mod;
            long long y = yNumberator / mod;
            
            minX = min(minX, x);
            minY = min(minY, y);
            
            maxX = max(maxX, x);
            maxY = max(maxY, y);
            
            coords.push_back({x, y});
            
        }
    }
    
    string row = string(maxX - minX + 1, '.');
    vector<string> answer(maxY - minY + 1, row);
    
    for(auto &it : coords){
        answer[abs(it.second - maxY)][abs( it.first - minX)] = '*';
    }
    
    return answer;
}

 

 

 

728x90