티스토리 뷰

www.acmicpc.net/problem/7453

 

7453번: 합이 0인 네 정수

첫째 줄에 배열의 크기 n (1 ≤ n ≤ 4000)이 주어진다. 다음 n개 줄에는 A, B, C, D에 포함되는 정수가 공백으로 구분되어져서 주어진다. 배열에 들어있는 정수의 절댓값은 최대 228이다.

www.acmicpc.net

입력으로 주어진 A, B, C, D 배열에 대해 4개 수의 합이 0이 되는 순서쌍의 개수를 구하는 문제입니다.

 

처음 생각한 것

1. A, B의 가능한 합을 모두 구한다. ( AB 배열에 저장 )

2. C, D의 가능한 합을 모두 구한다. ( CD 배열에 저장 )

3. C, D를 정렬한다.

4. binary search를 이용해 AB의 모든 원소를 key로 하여 CD 배열에서 key의 index를 찾는다.

5. 찾은 경우 해당 index의 앞 뒤로 같은 것의 개수를 카운트한다.

=> 시간 초과

 

시간 초과를 해결하기 위해 lower_bound와 upper_bound를 이용했습니다.

(직접 구현하니 70% 쯤에서 시간초과가 뜬다....)

=> key를 기준으로 앞뒤로 같은 것 찾는 과정을 안 해도 됨. algorithm의 lower_bound, upper_bound 이용하여 key에 근접한 index를 구한다.

 

lower_bound : key와 같은 값 있으면 가장 작은 index를 구한다. 없으면 key보다 큰 수 중 가장 작은 원소의 index를 구한다.

 

upper_bound : key보다 큰 원소 중 가장 작은 원소의 index를 구한다.

 

코드는 다음과 같습니다.

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

// A,B 와 C,D 의 합을 계산한다.
// C,D의 합만 오름차순으로 정렬한다.
// lower_bound, upper_bound 함수를 이용해 -num 에 가까운 index를 찾는다.
// lower_bound : key와 같은 값 있으면 가장 작은 index를 구한다.
// 없으면 key보다 큰 수 중 가장 작은 원소의 index를 구한다.
// upper_bound : key보다 큰 원소 중 가장 작은 원소의 index를 구한다.
// key (여기서는 -num) 와 같은 값 존재할 때 조건 만족하므로 upper - lower를 더한다.

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	int n;
	long long arr[4000][4];
	long long result = 0;
	vector<long long>cd;

	cin >> n;

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < 4; j++) {
			cin >> arr[i][j];
		}
	}

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			cd.push_back(arr[i][2] + arr[j][3]);
		}
	}

	sort(cd.begin(), cd.end());

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			long long num = arr[i][0] + arr[j][1];
			long long lower = lower_bound(cd.begin(), cd.end(), (-1) * num) - cd.begin();
			long long upper = upper_bound(cd.begin(), cd.end(), (-1) * num) - cd.begin();

			if ((-1) * num == cd[lower])
				result += (upper - lower);
		}
	}

	cout << result;
}

 

'알고리즘 > 백준' 카테고리의 다른 글

백준 / 1311 할 일 정하기 1 C++  (0) 2021.02.24
백준 / 15681 트리와 쿼리 C++  (0) 2021.02.24
백준 / 17472 다리 만들기 2 C++  (0) 2021.02.23
백준 / 15685 드래곤 커브 C++  (0) 2021.02.22
백준 / 2589 보물섬 C++  (0) 2021.02.20
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
TAG
more
«   2024/12   »
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
글 보관함