티스토리 뷰
#include <stdio.h>
#include <stdlib.h>
int cmp(const void*a, const void*b) {
return *(int*)a-*(int*)b;
}
int main(void) {
int n, nn;
scanf("%d",&n);
nn = n*n;
int arr[4][n],L[nn],R[nn];
for(int i=0;i<n;i++)scanf("%d %d %d %d",&arr[0][i],&arr[1][i],&arr[2][i],&arr[3][i]);
for(int i=0;i<n;i++) {
for(int j=0;j<n;j++) {
L[i*n+j] = arr[0][i] + arr[1][j];
R[i*n+j] = arr[2][i] + arr[3][j];
}
}
qsort(L,nn,4,cmp);
qsort(R,nn,4,cmp);
int left = 0, right = nn-1, tmp, LV,RV,LL,RR;
long long ans = 0;
while(left < nn && right >= 0) {
tmp = L[left] + R[right];
if(tmp > 0) right--;
else if(tmp < 0) left++;
else {
LV = L[left]; RV = R[right]; LL = 0; RR = 0;
do {LL++; left++;} while(left < nn && L[left] == LV);
do {RR++; right--;} while(right >= 0 && R[right] == RV);
ans += (long long)LL * RR;
}
}
printf("%lld",ans);
return 0;
}
풀이 : MITM
브루트포스로 처리하면 4000^4 = 256,000,000,000,000 입니다. 문제에서 주어진 소요시간 한도가 12초 이나 너무나도 부족합니다.
이를 해결하기위해 MITM 이라는 쪼개기 기법을 사용할 겁니다.
4000^4 에서 4000^2, 4000^2 개의 각각의 브루트포스를 이용하여, 부분합의 배열을 만듭니다
-- 2 * 4000^2 = 32,000,000
그런 다음 구한 두개의 부분합 배열을 오름차순 정렬 한 후, 두포인터를 이용하여 서로의 부분합을 더해서 0이 되는것을 확인합니다.
저는 위의 코드에서 0번 1번 배열의 부분합과, 2번 3번 배열의 부분합을 만든다음, 0번 1번 부분합은 0번 index 부터 2번 3번 부분합은 n*n-1 번 index 부터 시작합니다.
만약 두 부분합의 합이 0보다 크면 2,3번 부분합의 index을 감소시키고, 0보다 작다면 0,1번 부분합의 index을 증가시킵니다.
0을 찾았다면, 이제 중복 체크를 해야합니다. 합을 0을 이루도록 하는 것이 0,1번 부분합엔 연속적으로 몇개, 2,3번 부분합엔 연속적으로 몇개인지를 각각 구한다음 이들의 곱을 ans에 누적합니다.
중복체크를 하는 이유

이래야 정확한 개수를 구할 수 있습니다. 그냥 합이 0이라고 양쪽의 포인터를 옮겨버리면 정확한 처리가 불가합니다.
'c언어 > BAEKJOON' 카테고리의 다른 글
| c언어 10958번 Ice Hockey World Championship (백준) (0) | 2025.08.22 |
|---|---|
| c언어 9007번 카누 선수 (백준) (0) | 2025.08.22 |
| c언어 2087번 암호문 (백준) (0) | 2025.08.21 |
| c언어 1450번 냅색문제 (백준) (0) | 2025.08.21 |
| c언어 1208번 부분수열의 합 2 (백준) (0) | 2025.08.20 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 그래프
- 누적합
- DFS
- 1835번
- BFS
- DP
- 세그먼트 트리
- Segment Tree
- Lazy Propagation
- XOR
- 구현
- 최소 스패닝 트리
- 스택
- 덱
- java
- 브루트포스
- 문자열
- 그리디
- find
- C언어
- 정렬
- Krustal
- C++
- 1835
- 백준
- 오프라인 쿼리
- 누적 합
- PASCAL
- union
- 기하학
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
글 보관함
