성능 요약
메모리: 4.22 MB, 시간: 0.01 ms
문제 설명
Ax + By + C = 0
으로 표현할 수 있는 n
개의 직선이 주어질 때, 이 직선의 교점 중 정수 좌표에 별을 그리려 합니다.
예를 들어, 다음과 같은 직선 5개를
2x - y + 4 = 0
-2x - y + 4 = 0
-y + 1 = 0
5x - 8y - 12 = 0
5x + 8y + 12 = 0
좌표 평면 위에 그리면 아래 그림과 같습니다.
이때, 모든 교점의 좌표는 (4, 1)
, (4, -4)
, (-4, -4)
, (-4, 1)
, (0, 4)
, (1.5, 1.0)
, (2.1, -0.19)
, (0, -1.5)
, (-2.1, -0.19)
, (-1.5, 1.0)
입니다. 이 중 정수로만 표현되는 좌표는 (4, 1)
, (4, -4)
, (-4, -4)
, (-4, 1)
, (0, 4)
입니다.
만약 정수로 표현되는 교점에 별을 그리면 다음과 같습니다.
위의 그림을 문자열로 나타낼 때, 별이 그려진 부분은 *
, 빈 공간(격자선이 교차하는 지점)은 .
으로 표현하면 다음과 같습니다.
"..........."
".....*....."
"..........."
"..........."
".*.......*."
"..........."
"..........."
"..........."
"..........."
".*.......*."
"..........."
이때 격자판은 무한히 넓으니 모든 별을 포함하는 최소한의 크기만 나타내면 됩니다.
따라서 정답은
"....*...."
"........."
"........."
"*.......*"
"........."
"........."
"........."
"........."
"*.......*"
입니다.
직선 A, B, C
에 대한 정보가 담긴 배열 line
이 매개변수로 주어집니다. 이때 모든 별을 포함하는 최소 사각형을 return 하도록 solution 함수를 완성해주세요.
제한사항
- 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
직선 y = 1
, x = 1
, x = -1
는 다음과 같습니다.
(-1, 1)
, (1, 1)
에서 교점이 발생합니다.
따라서 정답은
"*.*"
입니다.
입출력 예 #3
직선 y = x
, y = 2x
는 다음과 같습니다.
(0, 0)
에서 교점이 발생합니다.
따라서 정답은
"*"
입니다.
입출력 예 #4
직선 y = x
, y = 2x
, y = 4x
는 다음과 같습니다.
(0, 0)
에서 교점이 발생합니다.
따라서 정답은
"*"
입니다.
참고 사항
Ax + By + E = 0
Cx + Dy + F = 0
두 직선의 교점이 유일하게 존재할 경우, 그 교점은 다음과 같습니다.
또, AD - BC = 0인 경우 두 직선은 평행 또는 일치합니다.
코드
#include <string>
#include <vector>
#include <unordered_set>
#include <climits>
#include <algorithm>
using namespace std;
struct pair_hash {
template <class T1, class T2>
std::size_t operator () (const std::pair<T1, T2>& p) const {
auto h1 = std::hash<T1>{}(p.first);
auto h2 = std::hash<T2>{}(p.second);
return h1 ^ h2;
}
};
vector<string> solution(vector<vector<int>> line) {
vector<string> answer;
unordered_set<pair<int, int>,pair_hash> locations;
for(int i = 0; i < line.size(); i++)
{
vector<int> A = line[i];
for(int j = i+1; j < line.size(); j++)
{
vector<int> B = line[j];
long long mod = 1LL * A[0] * B[1] - 1LL* A[1] * B[0];
if(mod != 0)
{
long long x = 1LL * A[1] * B[2] - 1LL * A[2] * B[1];
long long y = 1LL * A[2] * B[0] - 1LL * A[0] * B[2];
if(!(x % mod) && !(y % mod))
{
locations.insert(pair(x / mod, y / mod));
}
}
}
}
int x_min = INT_MAX;
int y_min = INT_MAX;
int x_max = INT_MIN;
int y_max = INT_MIN;
for(const auto& location : locations)
{
int x = location.first;
int y = location.second;
x_min = min(x_min, x);
y_min = min(y_min, y);
x_max = max(x_max, x);
y_max = max(y_max, y);
}
long long x_size = x_max - x_min;
long long y_size = y_max - y_min;
string star_string = "";
for(long long i = 0; i <= x_size; i++)
{
star_string += '.';
}
answer = vector<string>(y_size+1, star_string);
for(const auto & location : locations)
{
int x = abs(location.first - x_min);
int y = abs(location.second - y_max);
answer[y][x] = '*';
}
return answer;
}
테스트 결과
'코딩테스트' 카테고리의 다른 글
[백준][Gold IV] 줄세우기 - 2631 (0) | 2024.01.06 |
---|---|
[level 2] 미로 탈출 - 159993 (1) | 2023.12.27 |
[level 2] 괄호 변환 - 60058 (0) | 2023.12.25 |
[level 2] 쿼드압축 후 개수 세기 - 68936 (0) | 2023.11.25 |
[level 2] 호텔 대실 - 155651 (0) | 2023.11.17 |