처음에 두 점씩 이어서 선분을 만드는 경우의 수를 잘못계산했다.
총 점이 4개이기떄문에, 4*3=12. 즉 12가지 경우의수가 있을거라생각하고 진행했다가 틀렸다.
위 로직대로하면 말이안된다.
예를들어 점 a,b,c,d가 있을때 a-b, b-c 이렇게 연결되는 경우가있기때문이다.
이때에는 b가 겹치기도하고, d는 선분에 포함되어있지않게때문에 문제조건과 맞지않다.
잘 생각해보면 4개의 점을 모두 선분에 포함시켜야하고, 각 선분에는 겹치지않는 점 2개만 있어야한다.
따라서 경우의수는 3가지밖에없고 이를 코드로 직접 다 작성했다.
class Solution {
public int solution(int[][] dots) {
int answer = 0;
int[][] line = new int[3][4];
line[0][0] = Math.abs(dots[0][0] - dots[1][0]);
line[0][1] = Math.abs(dots[0][1] - dots[1][1]);
line[0][2] = Math.abs(dots[2][0] - dots[3][0]);
line[0][3] = Math.abs(dots[2][1] - dots[3][1]);
line[1][0] = Math.abs(dots[0][0] - dots[2][0]);
line[1][1] = Math.abs(dots[0][1] - dots[2][1]);
line[1][2] = Math.abs(dots[1][0] - dots[3][0]);
line[1][3] = Math.abs(dots[1][1] - dots[3][1]);
line[2][0] = Math.abs(dots[0][0] - dots[3][0]);
line[2][1] = Math.abs(dots[0][1] - dots[3][1]);
line[2][2] = Math.abs(dots[1][0] - dots[2][0]);
line[2][3] = Math.abs(dots[1][1] - dots[2][1]);
for(int i =0; i<3;i++) {
int gcd1 = GCD(line[i][0] ,line[i][1]);
if(gcd1 != 1) {
line[i][0] = line[i][0]/gcd1;
line[i][1] = line[i][1]/gcd1;
}
int gcd2 = GCD(line[i][2] ,line[i][3]);
if(gcd2 != 1) {
line[i][2] = line[i][2]/gcd2;
line[i][3] = line[i][3]/gcd2;
}
if(line[i][0] == line[i][2] && line[i][1] == line[i][3]) {
answer=1;
break;
}
}
return answer;
}
public int GCD(int a,int b) {
int max = 1;
for(int i=1; i<=a && i<=b; i++) {
if(a%i ==0 && b%i==0) {
max = i;
}
}
return max;
}
}
내 코드의 가독성이 조금 좋지않은것같아서 다른 코드도 공부한다.
import java.lang.Math;
class Solution {
private int xPos = 0;
private int yPos = 1;
private int[][] checkCases = {{0, 1, 2, 3}, {0, 2, 1, 3}, {0, 3, 1, 2}};
public int solution(int[][] dots) {
int answer = 0;
for (int[] checkCase : checkCases) {
if (checkParallel(checkCase, dots)) {
answer = 1;
break;
}
}
return answer;
}
private boolean checkParallel(int[] checkCase, int[][] dots) {
int xPos1 = dots[checkCase[0]][xPos];
int yPos1 = dots[checkCase[0]][yPos];
int xPos2 = dots[checkCase[1]][xPos];
int yPos2 = dots[checkCase[1]][yPos];
int xPos3 = dots[checkCase[2]][xPos];
int yPos3 = dots[checkCase[2]][yPos];
int xPos4 = dots[checkCase[3]][xPos];
int yPos4 = dots[checkCase[3]][yPos];
// (y4 - y3)(x2 - x1) - (x4 - x3)(y2 - y1) 평행여부 조건
int chk = ((yPos4 - yPos3) * (xPos2 - xPos1)) - ((xPos4 - xPos3) * (yPos2 - yPos1));
if (chk == 0) {
return true;
}
return false;
}
}
가능한 경우의 수 조합을 checkCases 배열에 넣어준다.
앞에거 2개 뒤에거 2개끼리의 점을 잇는다는 뜻이다.
기울기가 같으면 평행하는것이므로 차이의 결과가 0이다.
이를 이용해서 진행할 수 있다.
class Solution {
public int solution(int[][] dots) {
int x1 = dots[3][0];
int y1 = dots[3][1];
for (int i = 0; i < 3; i++) {
int x2 = dots[i][0];
int y2 = dots[i][1];
int x3 = dots[(i+1)%3][0];
int y3 = dots[(i+1)%3][1];
int x4 = dots[(i+2)%3][0];
int y4 = dots[(i+2)%3][1];
if((y2-y1)/(double)(x2-x1)==(y4-y3)/(double)(x4-x3)){
return 1;
}
}
return 0;
}
}
기울기가 분수형태이므로 나눗셈을 했을 때 무한소수가 되는게있을것이다.
그리고 유한소수라고 하더라도 결과적으로 double형 유효자릿수의 이하 자리수가 다르다면, 기울기가 아주 살짝이라도 다르지않을까?
하는 의문에 나눗셈은 이용할 생각을 안했다.
그런데 이렇게 해도 정답처리가된다.
내가 잘못생각한걸까?