| numbers | return |
|---|---|
| "17" | 3 |
| "011" | 2 |
각 종이 조각을 붙여서 소수를 만들어야 하는데, 종이를 모두 필수로 붙여야 되는 것이 아니고 하나씩도 검사를 해봐야되기 때문에 완전탐색을 통해 진행할 것이다.
-> dfs를 통해서 구현한다고 하면 O(N!)만큼의 시간복잡도가 발생하는데, numbers의 길이가 최대 7이기 때문에 적당할 것으로 보인다.
11과 011은 같은 숫자로 취급되고, 같은 수가 여러번 나올 경우가 많으니, unordered_set<int>에 dfs를 통한 숫자를 저장하고 이를 소수 검사를 진행하면 될 것으로 보인다.
소수 찾는 함수의 구현은 배열로 저장(에라토스테네스의 체)보다는 값을 지속적으로 소수 검사하는 것이 나을 것으로 보인다.
-> 소수 검사 시에 O(logN)의 시간복잡도가 발생하는데, dfs랑 같이 사용하니 최종적으로 O(N!)만큼의 시간복잡도가 발생할 것으로 유추할 수 있다.
#include <string>
#include <vector>
#include <unordered_set>
using namespace std;
// 소수 검사 함수
bool isPrime(int n){
if(n == 0 || n == 1) return false;
for(int i = 2; i * i <= n; i++){
if(n % i == 0){
return false;
}
}
return true;
}
unordered_set<int> numberSet; // dfs한 값들 저장
vector<bool> visited; // dfs 방문 여부
void dfs(int idx, int n, string& numbers, string& str){
if(idx > n){
return;
}
for(int i = 0; i < n; i++){
if(visited[i]) continue;
visited[i] = true;
str += numbers[i];
numberSet.insert(stoi(str));
dfs(idx + 1, n, numbers, str);
visited[i] = false;
str.pop_back();
}
}
int solution(string numbers) {
int answer = 0;
// 만들 수 있는 모든 숫자 unordered_set에 저장
string str = "";
visited = vector<bool>(numbers.size(), false);
dfs(0, numbers.size(), numbers, str);
// 소수인지 확인
for(auto it = numberSet.begin(); it != numberSet.end(); ++it){
if(isPrime(*it)){
answer++;
}
}
return answer;
}
| arr | result |
|---|---|
| [[1,1,0,0],[1,0,0,0],[1,0,0,1],[1,1,1,1]] | [4,9] |

2^n이기 때문에 절반인 2^(n-1)을 기준으로 분리된 부분을 전부 확인한 후에 같은 값이라면 즉시 0 또는 1의 값을 넣으면 될 것 같다.O(N^2) 만큼 발생할 것으로 유추된다. (N = 1024)#include <string>
#include <vector>
using namespace std;
vector<int> answer{0,0};
void divide(int start_x, int end_x, int start_y, int end_y, vector<vector<int>>& arr){
// (start_x ~ end_x)(start_y ~ end_y) 전부 같은 값인지 검사
bool isFlag = true;
int k = arr[start_y][start_x];
for(int i = start_y; i < end_y; i++){
for(int j = start_x; j < end_x; j++){
if(k != arr[i][j]){
isFlag = false;
break;
}
}
if(!isFlag) break;
}
// 같은 값이라면
if(isFlag){
if(k == 0)
answer[0]++;
else
answer[1]++;
return;
}
// 아니라면 분할
int n = (end_x - start_x) / 2;
divide(start_x, end_x - n, start_y, end_y - n, arr);
divide(start_x + n, end_x, start_y, end_y - n, arr);
divide(start_x, end_x - n, start_y + n, end_y, arr);
divide(start_x + n, end_x, start_y + n, end_y, arr);
}
vector<int> solution(vector<vector<int>> arr) {
divide(0, arr.size(), 0, arr.size(), arr);
return answer;
}