PS
프로그래머스. 소수 찾기
tose33
2021. 7. 27. 16:49
https://programmers.co.kr/learn/courses/30/lessons/42839
코딩테스트 연습 - 소수 찾기
한자리 숫자가 적힌 종이 조각이 흩어져있습니다. 흩어진 종이 조각을 붙여 소수를 몇 개 만들 수 있는지 알아내려 합니다. 각 종이 조각에 적힌 숫자가 적힌 문자열 numbers가 주어졌을 때, 종이
programmers.co.kr
1. 주어진 숫자들을 1개 뽑는 조합, 2개 뽑는 조합, ... , 모두 뽑는 조합을 구한다.
주어진 숫자가 "17" 이라면
조합은 {1}, {7}, {17}
2. 구한 조합들에 대해 가능한 모든 순열을 구한다.
조합 {1} : 1
조합 {7} : 7
조합 {17} : 17, 71
3. 만들어진 순열이 소수인지 판단하고 소수가 맞다면 새로운 ans 벡터에 푸쉬한다. (중복검사 후)
4. ans 벡터의 크기가 답이다
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> ans;
int num;
bool mark[8];
// 전달받은 순열이 소수인지 판별
bool IsItPrime(vector<char> comb)
{
bool isPrime = false;
string str = "";
for(int i = 0; i < comb.size(); i++)
{
str += comb[i];
}
// string to integer
num = stoi(str);
// 0,1은 소수가 아님
if(num <= 1) return false;
// 2,3은 소수
if(num == 2 || num == 3) return true;
// 2부터 num-1까지 중 나눠서 떨어지는 수가 있으면 소수가 아님
for(int i = 2; i < num; i++)
{
if(num % i == 0)
{
return false;
}
}
return true;
}
// 소수로 판별된 숫자가 ans 벡터에 없다면 푸쉬함
void PushToAns()
{
bool duplicated = false;
for(int i = 0; i < ans.size(); i++)
{
if(ans[i] == num)
{
duplicated = true;
break;
}
}
// 중복되지 않았다면 ans 벡터에 푸쉬
if(!duplicated) ans.push_back(num);
}
int solution(string numbers) {
int answer = 0;
sort(numbers.begin(), numbers.end(), greater<>());
for(int idx = 1; idx <= numbers.size(); idx++)
{
for(int i = 0; i < numbers.size(); i++)
{
if(i < idx) mark[i] = true;
else mark[i] = false;
}
do {
vector<char> comb;
// 만들어진 조합을 comb 벡터에 푸쉬한다
for(int i = 0; i < numbers.size(); i++)
{
if(mark[i]) comb.push_back(numbers[i]);
}
// 만들어진 조합으로 모든 순열을 구한다
do {
// 소수가 맞다면
if(IsItPrime(comb))
PushToAns();
}while(prev_permutation(comb.begin(), comb.end()));
}while(prev_permutation(mark, mark+numbers.size()));
}
answer = ans.size();
return answer;
}
다음날 다시 풀어봄.
다른 분들의 코드를 본 결과
가능한 모든 순열을 먼저 구하고 1개부터 n개 까지 뽑는 조합을 구하는것이 더 쉬운것 같다.
(이전에 내가 푼방식은 정반대였다, 조합을 구하고 그에따른 모든 순열을 구함)
그리고 unique와 erase를 이용해서 중복제거도 추가했다.
#include <string>
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
// 가능한 모든 수들이 들어감
vector<int> ans;
bool isPrime(int n)
{
if(n < 2) return false;
for(int i = 2; i < n; i++)
if(n % i == 0)
return false;
return true;
}
int solution(string numbers) {
int answer = 0;
sort(numbers.begin(), numbers.end());
do {
string str = "";
for(int i = 0; i < numbers.size(); i++)
{
str.push_back(numbers[i]);
ans.push_back(stoi(str));
}
} while(next_permutation(numbers.begin(), numbers.end()));
// 중복 제거
sort(ans.begin(), ans.end());
ans.erase(unique(ans.begin(), ans.end()), ans.end());
for(int i = 0; i < ans.size(); i++)
{
if(isPrime(ans[i]))
answer++;
}
return answer;
}