정렬:
삼중 합 세기:
Lower, Upper Binary Search:
삼중 합의 경우의 수 세기:
using System.Text;
namespace BOJ
{
class No_3151
{
static void Main()
{
int n = int.Parse(Console.ReadLine());
int[] array = Array.ConvertAll(Console.ReadLine().Split(), int.Parse);
Array.Sort(array);
long answer = ThreeSumCount(array);
Console.WriteLine(answer);
}
static long ThreeSumCount(int[] arr)
{
long count = 0;
int n = arr.Length;
for (int i = 0; i < n - 2; i++)
{
for (int j = i + 1; j < n - 1; j++)
{
int target = -(arr[i] + arr[j]);
int lowerIndex = LowerBinarySearch(arr, target, j + 1, n - 1);
int upperIndex = UpperBinarySearch(arr, target, j + 1, n - 1);
if (lowerIndex != -1 && upperIndex != -1)
{
count += (upperIndex - lowerIndex + 1);
}
}
}
return count;
}
static int LowerBinarySearch(int[] arr, int target, int x, int y)
{
int start = x;
int end = y;
int result = -1;
while (start <= end)
{
int mid = (start + end) >> 1;
if (arr[mid] >= target)
{
result = mid;
end = mid - 1;
}
else
{
start = mid + 1;
}
}
return result;
}
static int UpperBinarySearch(int[] arr, int target, int x, int y)
{
int start = x;
int end = y;
int result = -1;
while (start <= end)
{
int mid = (start + end) >> 1;
if (arr[mid] <= target)
{
result = mid;
start = mid + 1;
}
else
{
end = mid - 1;
}
}
return result;
}
}
}
Upper에서 Lower를 뺀 이유는 같은 숫자가 존재할 수 있고 같은 수를 중복으로 선택이 가능하기 때문에 원하는 값의 최대 인덱스와 최소 인덱스가 필요하다고 판단하여 Upper과 Lower 코드를 제작하였다.
나의 코드는 두 수를 고를 상태에서 이분 탐색을 진행하기 때문에 의 시간복잡도를 가지고 있는다. 사실 이 로직을 생각하고 작성하여 제출하였을 때, 까지 가능하기 때문에 최악의 경우 4초 이내에 수행하지 못할 것 같았지만 일단 제출해보자는 생각으로 코드를 작성하여 제출해보았더니 정답을 받아 약간 당황스러웠다. 다른 분들의 코드를 확인하고 (물론 C#으로 된 코드는 없었...) 다른 풀이를 이용하여 풀어봐야겠다.
브루트포스 알고리즘
정렬
이분 탐색
두 포인터