수학은 비대면 강의입니다 - 19532

Update:     Updated:

Category:

Tags:


19532번: 수학은 비대면강의입니다


시행 착오 1 🥲

연립 일차 방정식의 경우, 두 직선의 교차점은 하나이기 때문에 x,y도 모두 하나씩 존재

a, b, c, d, e, f = map(int, input().split())

a1 = a * d
b1 = b * d
c1 = c * d
d1 = d * a
e1 = e * a
f1 = f * a

y = (c1 - f1) / (b1 - e1)
x = (c1 - b1 * y) / (a1)
print(int(x), int(y))  # x,y는 모두 정수임 


위의 방법으로 풀었더니 -> 런타임 에러 발생(zero-division error)

(b1 - e1)이랑 a1이 0인 경우를 고려해주지 않아서 발생한 것 같다. 이 말은 a 혹은 d가 0일 경우가 존재하는데, 이때 나머지 값들도 모두 0을 곱해주게 되는 문제도 발생한다. 예외 처리를 시도해보려고 했지만, 애초에 초반에 a와 d를 곱할 때부터 경우를 나눠서 해줘야해서 매우 복잡했다.

시행 착오 2 🥲

결국 더 간단하게 해결할 방법을 찾아봤는데,

행렬의 곱셈으로 해결할 수 있었다..!

image

선대 공부를 좀 곁들여보면,

행렬은 연립 일차방정식의 해를 구하기 위해서 연구되었다.

행렬을 이용한 연립 일차방정식 풀이법 2가지는 :

  • 가우스-조던-소거법 : 행렬을 간소화해서 연립방정식 재구성
  • 역행렬을 이용하는 방식 : $Ax = B$에서 $A$의 역행렬이 존재하는 경우, 양변에 $A$의 역행렬을 곱해서 $x$의 해를 구할 수 있다. (존재하지 않는 경우: 해 존재 X)

    image

a, b, c, d, e, f = map(int, input().split())

mat = [a, b, d, e]
det = a * e - b * d
mat_rev = [e / det, (-b) / det, (-d) / det, a / det]

x = (mat_rev[0] * c + mat_rev[1] * f)
y = (mat_rev[2] * c + mat_rev[3] * f)

print(x, y)  # 1.9999999999999998  -1.0


위의 방법을 적용해서 풀어봤지만 소숫점에서 미세한 오차가 발생

이유를 찾아본 결과, 우리가 사용하는 십진법에서의 소수는 컴퓨터가 이해하는 이진 소수로 정확하게 변환될 수 없다고 한다.
결국 값을 근사하게 되면서 문제가 발생하는 것.

15. 부동 소수점 산술: 문제점 및 한계


맞았습니다! 코드

나눗셈을 바로 하지 않고 계산 후 마지막에 하는 방식으로 수정했다.

# 맞은 풀이 - 행렬의 곱셈
a, b, c, d, e, f = map(int, input().split())

mat = [a, b, d, e]
mat_rev = [e, -b, -d, a]
det = a * e - b * d

x = (mat_rev[0] * c + mat_rev[1] * f) / det
y = (mat_rev[2] * c + mat_rev[3] * f) / det

print(int(x), int(y)) # 2  -1





맨 위로 이동하기