[백준 C++] 1064 평행사변형

이성훈·2021년 11월 5일
0
post-custom-banner

문제

평행사변형은 평행한 두 변을 가진 사각형이다. 세 개의 서로 다른 점이 주어진다. A(xA,yA), B(xB,yB), C(xC,yC)

이때, 적절히 점 D를 찾아서 네 점으로 평행사변형을 만들면 된다. 이때, D가 여러 개 나올 수도 있다.

만들어진 모든 사각형 중 가장 큰 둘레 길이와 가장 작은 둘레 길이의 차이를 출력하는 프로그램을 작성하시오. 만약 만들 수 있는 평행사변형이 없다면 -1을 출력한다.

입력

첫째 줄에 xA yA xB yB xC yC가 주어진다. 모두 절댓값이 5000보다 작거나 같은 정수이다.

출력

첫째 줄에 문제의 정답을 출력한다. 절대/상대 오차는 10-9까지 허용한다.

https://www.acmicpc.net/problem/1064

평행사변형의 둘레는 주어지는 세점으로 만들수있는 세직선의 길이를 각각구하고,
이 3개중 2개씩뽑아 (2개의합 x 2)가 둘레가되겠다.

가장먼저, 평행사변형이 만들어지지 않는경우는,

세점이모두 한 직선에있을때이다.

가장큰 실수 3가지정도때문에 애를 먹었는데, 정리해보겠다.

  1. C++의 나눗셈 연산자 ( / )는 피연산자가 둘다 정수면 나머지를 버린다.

그동안 입력값을 int에 저장했는데, 이것을 모두 doubl로 형변환할바에 애초부터 double로 받았으면됬다.

  1. scanf로 정수를 double에 받을때 %f 가 아닌 %lf 로 받아야한다.

즉, double에 저장할것이면 %lf 를 사용했어야했다.

  1. 세점의 위치로 기울기값을 비교하여 한직선인지 체크할때
    절댓값으로 비교했어야했다.

두점을 지나는 직선의 기울기 계산 미스였다.


이렇게 수정을 한뒤 제출을 했으나.. 틀렸다고 나왔다.

결국 for문을 버리고 수기로 둘레의길이를 perimeters 배열에담아, C++의 max, min함수를 사용하여 출력하였다.

소숫점연산이 참 익숙치 않나보다.

#define _CRT_SECURE_NO_WARNINGS //scanf오류 없앰
#include <bits/stdc++.h>
using namespace std;

int main(void) {
	double x1, y1, x2, y2, x3, y3;
	scanf("%lf%lf%lf%lf%lf%lf", &x1, &y1, &x2, &y2, &x3, &y3);
	//두직선의 기울기가 같으면 한직선상이므로 -1출력

	if ((abs(y2 - y1) / abs(x2 - x1)) == (abs(y3 - y2) / abs(x3 - x2))) {
		printf("-1.0");
	}
	else {
		double lines[3];
		lines[0] = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); //2 ,1
		lines[1] = sqrt((x3 - x1) * (x3 - x1) + (y3 - y1) * (y3 - y1)); //3, 1
		lines[2] = sqrt((x3 - x2) * (x3 - x2) + (y3 - y2) * (y3 - y2)); //3, 2
		double perimeters[] = { lines[0] * 2 + lines[1] * 2,
								lines[1] * 2 + lines[2] * 2,
								lines[2] * 2 + lines[0] * 2 };
		double maxPerimeter = 0.0, minPerimeter = 0.0;
		maxPerimeter = max(perimeters[0], max(perimeters[1], perimeters[2]));
		minPerimeter = min(perimeters[0], min(perimeters[1], perimeters[2]));
		printf("%.16f", maxPerimeter - minPerimeter);
	}
}
profile
I will be a socially developer
post-custom-banner

0개의 댓글