Boj 10800) 컬러볼
문제
방법 1
설명
size
에 대한 전체 공을 누적합을 구하고, color
별로 따로 그룹을 만들어서 누적합을 구한다. 이때 정렬을 미리 한 다음 누적합을 하여 이분탐색을 통해 누적합의 몇번 인덱스까지 가야하는지 알 수 있도록 한다. 그리고 전체 누적합에서 같은 색깔에 대한 누적합만 빼낸다.
시간복잡도
O(\(N \log{N}\))
방법 2
설명
전제 공에 대한 누적합과 색깔 별 누적합으로 값을 구하는 과정에서 바로 공을 몇개 잡을 수 있는지 알 수 있다. 왜냐하면 이미 정렬된 상태이기 때문에 누적합의 결과가 곧 잡을 수 있는 공의 크기 합이기 때문이다. 하지만 sort()
로 인해 문제에서 요구한 대로 순서대로 구할 수 없다는 문제가 있다. 이는 인덱스를 저장해서 매핑하면 해결할 수 있다.
이때 공의 크기가 같은 경우를 잘 처리해줘야한다.
시간 복잡도
O(\(N\))
코드
struct B {
int color, size, idx;
bool Can(const B& in)
{
return color != in.color && size > in.size;
}
bool operator<(const B& in) { return size < in.size; }
};
B arr[200001];
int sum, sumc[200001], ans[200001];
int main()
{
int n; cin >> n;
for (int i = 0; i < n; i++)
{
cin >> arr[i].color >> arr[i].size;
arr[i].idx = i;
}
sort(arr, arr + n);
for (int i = 0, j = 0; i < n; i++)
{
while (arr[i].size > arr[j].size && j < n) // 따로 포인터를 두어 현재 다루는 size 보다 작은 경우만 모두 더한다.
{
sum += arr[j].size;
sumc[arr[j].color] += arr[j].size;
j++;
}
ans[arr[i].idx] = sum - sumc[arr[i].color];
}
for (int i = 0; i < n; i++)
cout << ans[i] << '\n';
}
댓글남기기