반응형
문제링크
https://www.acmicpc.net/problem/2746
문제 총평
- 케이스를 잘 생각해 낸다면 쉬웠던 문제
문제 접근방식
- 이번 문제는 처음에 접근을 너무 어렵게 해서 많이 틀렸습니다.
- 하지만 단순한 경우의 수라는걸 알면 쉽게 풀 수 있습니다.

정답코드
import sys; input = sys.stdin.readline
n = int(input())
arr = list(map(int, input().split()))
arr.sort()
s = sum(arr)
ans = 0
s1 = s-arr[-1]
num = [0] * (1000000+1)
for i in arr:
num[i] += 1
num[arr[-1]] -= 1
for i in set(arr[:-1]):
if s1-i-arr[-1] >= 0 and s1-i-arr[-1] <= 1000000 and num[s1-i-arr[-1]]:
if s1-i-arr[-1] == i:
ans += num[s1-i-arr[-1]] * (num[s1-i-arr[-1]]-1)
continue
ans += num[s1-i-arr[-1]] * num[i]
ans //= 2
num[arr[-2]] -= 1
s2 = s1-arr[-2]
if s2-arr[-2] <= 1000000 and s2-arr[-2] >= 0:
ans += num[s2-arr[-2]]
if s2-arr[-3] == arr[-3]:
ans += 1
print(ans)
- 먼저 가능한 경우는 3개로 생각할 수 있습니다.
- 첫번째. 배열의 최대 값(arr[-1])이 나머지 배열의 합에서 두 원소를 제거한 값과 같을 경우
- 두번째. 배열의 최대 값을 빼고(arr[-1]) 두 번째 최대값(arr[-2])이 나머지 배열의 합에서 한 원소를 제거한 값과 같을 경우
- 세번째. 배열의 최대 값 두개(arr[-1],arr[-2])를 빼고 나머지 최대값(arr[-3])이 나머지 배열의 합과 같은경우
- 첫번째의 경우에는 전체 합에서 최대값을 빼고 남은 전체 합에서 두 원소를 뺀 값이 최대값과 같은 경우입니다. -> 이 경우 전체 순회를 하면서 현재 순회 중인 값 i + j(전체 - 최대값 - i) 의 갯수 두개를 곱하면 됩니다.
- 하지만 i,j가 같은 경우에는 nC2 이므로 n*(n-1) 을 해줍니다. (마지막에 //2를 할것이므로 여기서는 //2를 안해줌)
- 그렇게 구한 모든 경우의 수를 2로 나눠줍니다. (전체를 돌면서 같은 경우를 두번씩 체크하므로)
- 두번째의 경우 전체합에서 최대값과 두번째 최대 값을 뺀 값이 특정 요소를 뺀 전체 값과 같으면 되므로 s2-arr[-2]를 세줍니다.
- 세번째의 경우에는 전체값-첫번째최대값-두번째최대값 = 세번째 최대값이 되면 됩니다.
문제 풀이 후 생각
- 풀이를 좀 더 간소화 할 수는 있지만 이게 명확해 보여서 3가지 경우를 나눴습니다.
- 그리고 원소의 최대값이 1000000 이므로 불가능한 경우를 조건 처리 해줬습니다.
- 수학적인 지식이 부족한게 느껴지네요...
모르는게 있다면 댓글 또는 godzz733@naver.com으로 메일 남겨 주세요
반응형
'알고리즘' 카테고리의 다른 글
| 백준 1313번 : 합성소수 (Python) (1) | 2024.01.13 |
|---|---|
| 백준 30505: SASA 마니또 (Python) (1) | 2024.01.10 |
| 백준 29793: 라라와 용맥 변환 (Python) (0) | 2023.09.15 |
| [백준] 13537 수열과 쿼리 1 - 머지소트트리(merge sort Tree) (Python) (0) | 2023.08.07 |
| [백준] 20442 ㅋㅋ루ㅋㅋ - 투 포인터 (Python) (2) | 2023.08.06 |