문제 : 소수 찾기
문제 설명
한자리 숫자가 적힌 종이 조각이 흩어져있습니다. 흩어진 종이 조각을 붙여 소수를 몇 개 만들 수 있는지 알아내려 합니다.
각 종이 조각에 적힌 숫자가 적힌 문자열 numbers가 주어졌을 때, 종이 조각으로 만들 수 있는 소수가 몇 개인지 return 하도록 solution 함수를 완성해주세요.
제한사항
- numbers는 길이 1 이상 7 이하인 문자열입니다.
- numbers는 0~9까지 숫자만으로 이루어져 있습니다.
- 013은 0, 1, 3 숫자가 적힌 종이 조각이 흩어져있다는 의미입니다.
분석
숫자가 소수인지 판단하는 것과 숫자를 조합하는 하는 것이 이 문제의 포인트이다. 소수인지 판단하는 건 에라토스테네스의 체를 이용하면 된다. 숫자를 조합하는 과정은 일단 조합으로 처리한 뒤 중복되는 수를 제거하면 된다.
구현
// 에라토스테네스의 체
// 주어진 숫자가 소수인지를 판단
bool is_primenum(int n)
{
if (n <= 1) return false;
int k = (int)sqrt(n);
for (size_t i = 2; i <= k; i++)
{
if (n%i == 0) return false;
}
return true;
}
vector<int> arr;
vector<bool> selected;
vector<int> tmp_num, real_num;
// 조합 수를 중복되지 않게 저장
// r은 자릿수
void make_num(int r)
{
int n = 0;
for (size_t i = 0; i < tmp_num.size(); i++)
{
n += pow(10, (r - 1))*tmp_num[i];
r--;
}
// 조합수 생성 후 중복된 수인지 판단
if (real_num.empty()) real_num.push_back(n);
else
{
for (size_t i = 0; i < real_num.size(); i++)
{
if (n == real_num[i]) return;
}
real_num.push_back(n);
}
}
// 조합
void DFS(int cnt, int r)
{
if (cnt == r)
{
make_num(r);
return;
}
for (size_t i = 0; i < arr.size(); i++)
{
if (selected[i] == true) continue;
selected[i] = true;
tmp_num.push_back(arr[i]);
DFS(cnt + 1, r);
tmp_num.pop_back();
selected[i] = false;
}
}
int solution(string numbers)
{
int answer = 0;
// 데이터 타입 변환
for (size_t i = 0; i < numbers.size(); i++)
{
int tmp = numbers[i] - '0';
arr.push_back(tmp);
selected.push_back(0);
}
// 조합 생성
for (size_t i = 1; i <= arr.size(); i++)
{
DFS(0, i);
}
// 겹치는 수 제외 후 소수인지 판단
for (size_t i = 0; i < real_num.size(); i++)
{
if (is_primenum(real_num[i]))
{
answer++;
}
}
return answer;
}
int main()
{
int a = solution("011");
cout << a << '\n';
return 0;
}
'알고리즘 > 프로그래머스' 카테고리의 다른 글
[프로그래머스 C++] - 괄호 변환 (0) | 2021.01.23 |
---|---|
[프로그래머스 C++] - 가장 큰 수 (0) | 2021.01.22 |
[프로그래머스 C++] - 문자열 압축 (0) | 2021.01.20 |
[프로그래머스 C++] - 카카오 프렌즈 컬러링북 (0) | 2021.01.19 |
[프로그래머스 C++] - 삼각 달팽이 (0) | 2021.01.18 |