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

1 minute read

문제 설명

https://programmers.co.kr/learn/courses/30/lessons/87377

제한사항

  • 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 크기 이내에서 표현됩니다.
  • 별이 한 개 이상 그려지는 입력만 주어집니다.

풀이

실패
범위 제약을 신경쓰지 않아서 헤매다가 문제를 틀렸다.
우선 A, B, C의 최대값이 10만인데, 판별식에서 두 수를 곱하게 되는데 10만 x 10만 = 100억 > 21억 이므로 int 형을 사용하면 오버플로우가 발생한다. 나는 10만 x 10만 의 결과값을 10억으로 착각해 int형을 사용해놓고 계속 다른 곳에서 문제점을 찾았다…ㅜ

코드

// 09:06 ~ 
#include <string>
#include <vector>
#include <cmath>
#include <iostream>
using namespace std;

vector<string> solution(vector<vector<int>> line) {
    vector<string> answer;
    vector<pair<long long,long long>> v;
    long long a,b,e; //Ax + By + E = 0
    long long c,d,f; //Cx + Dy + F = 0
    long long x,y;
    long long min_x = 10000000001, min_y = 10000000001, max_x = -10000000001, max_y = -10000000001;
    for(int i = 0; i < line.size(); ++i){
        a = line[i][0]; b = line[i][1]; e = line[i][2];
        for(int j = i + 1; j < line.size(); ++j){
            c = line[j][0]; d = line[j][1]; f = line[j][2];
            if(a*d == b*c) continue;
            if((b*f - e*d)%(a*d - b*c)!= 0 || (e*c - a*f)%(a*d - b*c) != 0) continue;
            x = (b*f - e*d)/(a*d - b*c);
            y = (e*c - a*f)/(a*d - b*c);
            
            if(x > max_x) max_x = x;
            if(x < min_x) min_x = x;
            if(y > max_y) max_y = y;
            if(y < min_y) min_y = y;
            v.push_back({x,y});
        }
    }
    
    string temp;
    temp.append(max_x - min_x + 1, '.');
   
    for(int i = 0; i < max_y - min_y + 1; ++i){
        answer.push_back(temp);
    }
    for(int i =0; i < v.size(); ++i){
        long long nx = v[i].first;
        long long ny = v[i].second;
        answer[max_y - ny][nx - min_x] = '*';
    }
    return answer;
}