1253. 좋다.

·2026년 6월 4일

백준 알고리즘

목록 보기
344/350

문제 해결 전략

  • n개의 수 중에서 나와는 다른 수 두개의 합으로 나를 만들수 있어야 한다.

  • 추가조건으로는 수의 위치가 다르면 값이 같아도 다른 수이다.
    -> 중복값인데 위치가 다르면 다르게 봐야 한다는 거다.

시간복잡도.

  • 1) n이 2000개이므로, 2000번의 타겟값 설정
  • 2) 모든 수를 정렬한 상태에서 끝점에서 가운데로 모이게 하면, 시간복잡도 2000
    => 최종적으로는 4000000 : 4백만 시간복잡도이다.

코드

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

using namespace std;




int main() 
{
	// 중복값이 있든 

	// 1 2 3 4 5 6 7 8 8 9 10

	// 이라고 한다면 
	// => 8이 중복이다...

	// 어쨋든 나보다 값이 낮은 쪽에 있는 걸로해야
	// 음수가 나올수 있나?? 


	// -5 -4 -1 1 1 2 3 4

	// 값이 나보다 크면 -4 , 4 
	// 낮춰야 하므로, right를 -- 
	
	// 타겟팅 정해놓고, 
	// 가운데로 모이는 투포인터로 할까??

	// 타겟팅 정하는 : 2000
	// 가운데 투포인터는 2000 번이므로 	
		// 4000000

	// 타겟 대상의 값과 동일하면 안된다.

	// 타겟에서 찾으면 카운팅하면 됨.

	int n;
	cin >> n;

	vector<long long> v(n);

	for (int i = 0; i < n; ++i)
		cin >> v[i];

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

	int answer = 0;

	for (int i = 0; i < n; ++i)
	{
		long long target = v[i];
		int tIdx = i;

		// 음수가 있을 수 있다.
		int lPos = 0;
		int rPos = n - 1;

		// -5 -4 -1 1 1 2 3 4
		while (lPos < rPos)
		{
			// 타겟값과 다른 두개의 수로 진행해야 한다. 

			// 수의 위치가 다르면 값이 같아도 다른수이므로
			// 인덱스 비교해야 한다. 

			if (lPos == tIdx)
			{
				lPos++;
				continue;
			}

			if (rPos == tIdx)
			{
				rPos--;
				continue;
			}
	
			long long sum = v[lPos] + v[rPos];

			if (sum == target)
			{			
				answer++;
				break;
			}
			else if (sum < target)
			{
				lPos++;
			}
			else if (sum > target)				
			{
				rPos--;				
			}
		}
	}

	cout << answer;

	return 0;
}
profile
🔥🔥🔥

0개의 댓글