문제 출처: https://www.acmicpc.net/problem/1940

시간제한이 2초인데 입력으로 들어오는 N이 15000까지라서 

O(N^2)으로 풀게된다면 시간초과가 뜰 수 도있습니다..

처음엔 고유값정렬 후 처음부터 하나씩  더해가며 M이될때 카운트했는데(버블정렬 처럼)

시간복잡도가 O(N^2)이여서 92ms가 걸려서  n개의 자료를 O(NlogN)으로 이분탐색을 응용하여 다시 풀어보았습니다.

결국 제가 제출한 코드의 시간복잡도는 퀵소트O(NlogN) +이분탐색O(NlogN)으로 

O(NlogN)이라고 유추할 수 있습니다.

어떤 방식으로 푸느냐에 따라 시간차이가 상당함을 알 수 있습니다.


알고리즘은 주석으로 대체하겠습니다.

#include<iostream>
#include<algorithm>
using namespace std;
int arr[15001];
int res = 0;

int main()
{
	int n, m;
	cin >> n >> m;
	cin.tie(0);
	cin.sync_with_stdio(false);

	for (int i = 0; i < n; i++)
	{
		cin >> arr[i];
	}
	//계산의 순서를 작은값부터 탐색하기위해 정렬시킴
	sort(arr, arr + n);

	//이분탐색 응용
	int start = 0, end = n - 1;
	while (start < end)
	{
		//start+end가 m이면
		//다음 탐색할 값은 start++,end--번쨰다.
		if (arr[start] + arr[end] == m)
		{
			start++, end--;
			res++;
		}
		//start+end<m이면 작은값+큰값<M이므로 작은값++;
		else if (arr[start] + arr[end] < m)
			start++;
		//start+end>m이면 작은값+큰값>M이므로 큰값--;
		else if (arr[start] + arr[end] > m)
			end--;
	}
	cout << res;

}


'문제풀이(BOJ) > 탐색' 카테고리의 다른 글

[백준 1668] 트로피 진열  (0) 2020.01.14

+ Recent posts