문제 링크: https://www.hackerrank.com/challenges/non-divisible-subset/problem

 

이 문제는 조건을 만족하는 부분집합(subset)중 가장 큰 부분집합의 크기를 구하는겁니다.

부분집합의 조건은 아무 두 원소의 합이 k의 배수가 아니어야 합니다.

 

일단 부분집합의 조건을 보면 입력값을 압축할 수 있습니다.

합이 k의 배수인지만 확인하면 되니까 입력값%k 값을 사용해 히스토그램으로 만들어줍니다. k<=100이기 때문에 10만개짜리 배열에서 100칸짜리 히스토그램으로 줄일 수 있습니다.

여기서 모든 부분집합을 만드는 경우는 k=100인 경우 2^100개 경우의 수가 나오는데 이건 너무 큰 값이니 불가능합니다.

 

합이 k가 되는 원소의 쌍을 생각해보면 (0, 0), (1, k-1), (2, k-2), ... , 이런식으로 되는데요, 두 원소가 동시에 배열에 들어갈 수 없으니 지금까지 더 많이 나온 mod값을 가진 수를 배열에 추가하면 됩니다.

유의할 점은 0은 한번만 들어갈 수 있고 k가 짝수일 때 k/2 역시 한번만 들어갈 수 있습니다. 두 번 들어가면 합이 k의 배수가 되기 때문입니다.

 

#pragma GCC optimize ("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,avx,avx2")

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;


typedef long long ll;

ll histogram[100];

int main()
{
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
#endif
	
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	
	int n, k;
	cin >> n >> k;

	for (int i = 0; i < n; ++i) {
		int tmp;
		cin >> tmp;
		++histogram[tmp % k];
	}

	ll subsets = 0;

	if (histogram[0])
		++subsets;

	for (int i = 1; i * 2 <= k; ++i) {
		if (i * 2 == k) subsets += (histogram[i] > 0);
		else subsets += max(histogram[i], histogram[k - i]);
	}

	cout << subsets << '\n';

	return 0;
}
반응형

'Online Judge > Hackerrank' 카테고리의 다른 글

[Hackerrank][C++] Absolute Permutation  (0) 2020.06.18
[Hackerrank][C++] Queen's Attack II  (0) 2020.06.17
[Hackerrank][C++] Equal  (2) 2020.05.26