오늘은 좀 쉬운거 잡고 오전에 다른거 해야지 했는데 예상보다 날 많이 괴롭혔다 이 문제가.
투 포인터를 사용하는 나쁘지 않은 편한 문제이다. 처음 보았을 때 정렬을 해두고 어떤 한 원소를 고정해두고 나머지 원소들을 투 포인터로 탐색하며 조합을 찾으면 좋겠다고 생각했다.
처음에는 선정한 한 개를 빼고 나머지들에서 투 포인터 탐색을 구현했다. 그렇게 되니 막 중복으로 찾고 난리가 나더라. 다시 생각해보니 어떤 원소 하나를 정하고 그 다음것부터 마지막까지만 계산하면 되는 문제였다.
그렇게 짜고 나니, 같은 값의 원소가 많이 있을 수 있다는 점이 걸렸다. L과 R이 가르키는 원소가 조합을 만족할 때, 우리는 두가지 상황에 빠진다.
하나는 두 원소가 값이 같을 경우. 이 때는 해당 값이 몇개 있는지 확인하고, k 개가 있다면 kC2를 구한다(R - L + 1 = k)
두 번째는 두 원소가 값이 다를경우, 이때는 각 값이 몇개 있는지 확인하고 두 값의 개수를 곱하면 조합의 개수가 나온다.
만약 첫번째 경우일경우, 더이상 탐색하는것이 의미가 없으므로 값을 구하고 break한다.
이 외에는 현재 조합이 0보다 클경우 조합의 값을 줄이기 위해 R을 1 감소하고, 그 반대의 경우 L을 1 증가시키며 탐색을 반복한다.
처음 이 접근이 시간초과가 나오지 않을까? 했는데 시간제한이 다른 문제들보다 넉넉한 편이라 괜찮겠지... 하고 짰다.
#include <iostream>
#include <vector>
#include <algorithm>
// std::ostream& operator<<(std::ostream& os, std::vector<int> vec)
// {
// for (int i = 0; i < vec.size(); i++)
// os << vec[i] << " ";
// os << '\n';
// return os;
// }
int main()
{
int N;
std::cin >> N;
std::vector<int> stdList;
long long cnt = 0;
for (int i = 0; i < N ; i++)
{
int student;
std::cin >> student;
stdList.push_back(student);
}
std::sort(stdList.begin(), stdList.end());
// std::cout << stdList;
for (int i = 0; i < N - 2; i++)
{
int l = i+1;
int r = N - 1;
int cur = stdList[i];
if (cur > 0)
break;
while (l < r)
{
int curLvl = cur + stdList[l] + stdList[r];
// 중복된 것 체크
if (curLvl == 0)
{
if (stdList[l] == stdList[r])
{
cnt += (int)((r - l + 1) * (r - l)) / 2;
break;
}
else
{
int rStart = stdList[r];
int rCnt = 0;
while (1)
{
if (stdList[r] != rStart)
break;
else
{
r--;
rCnt++;
}
}
int lStart = stdList[l];
int lCnt = 0;
while (1)
{
if (stdList[l] != lStart)
break;
else
{
l++;
lCnt++;
}
}
cnt += (lCnt * rCnt);
}
}
else if (curLvl > 0)
r--;
else
l++;
}
}
std::cout << cnt << '\n';
}
이걸 돌아가게 짠건 1시간? 정도 걸렸는데 계속 27%에서 틀려서 몇시간을 더 본것 같다.
같은 로직으로 짠 파이썬도 돌려봤는데 그건 PASS... 진짜 미춰버리는줄 알았다.
문제는 조합의 개수를 세는 cnt 변수가 int 였던것이다. 아니 그렇게 조합이 많을줄은 몰랐지... 에휴...
long long으로 바꾸니 잘 돌아간다... 하하... 오늘은 이거 보다가 허허... 했다.
넓게 보는 습관이 필요하다... 하하
오늘도 평온한 하루가 되길. 슨민.
'짜잘한 기록' 카테고리의 다른 글
백준 9251 LCS (0) | 2021.09.23 |
---|---|
백준 2473 세 용액 (0) | 2021.09.18 |
백준 14572 스터디 그룹 (0) | 2021.09.16 |
백준 16161 가장 긴 증가하는 팰린드롬 부분수열 (0) | 2021.09.15 |
백준 1644 소수의 연속합 (0) | 2021.09.14 |