코딩테스트 연습 - 블록 옮기기 | 프로그래머스
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
set<set<vector<int>>> visited;
int max_len;
vector<int> goal;
int answer = INT_MAX;
bool ft_arrived_goal(set<set<vector<int>>> positions, int second) {
set<set<vector<int>>>::iterator it;
for (it = positions.begin(); it != positions.end(); it++) {
if ((*it).find(goal) != (*it).end()) {
return (true);
}
}
return (false);
}
void ft_candidate(vector<vector<int>> board, set<set<vector<int>>>& positions, set<set<vector<int>>>& next_positions) {
set<set<vector<int>>> rtn;
vector<int> bigger;
vector<int> smaller;
set<set<vector<int>>>::iterator it;
for (it = positions.begin(); it != positions.end(); ++it) {
if (*((*it).begin()) > *((*it).rbegin())) {
bigger = *((*it).begin());
smaller = *((*it).rbegin());
} else {
bigger = *((*it).rbegin());
smaller = *((*it).begin());
}
bool horizontal;
if (bigger[0] - smaller[0] == 0) {
horizontal = true;
} else if (bigger[1] - smaller[1] == 0) {
horizontal = false;
}
if (horizontal == true) {
if ((smaller[0] != 0) && board[smaller[0] - 1][smaller[1]] == 0 && board[bigger[0] - 1][bigger[1]] == 0) {
set<vector<int>> temp_set;
vector<int> temp_vec = {smaller[0] - 1, smaller[1]};
temp_set.insert(smaller);
temp_set.insert(temp_vec);
if (visited.find(temp_set) == visited.end())
{
next_positions.insert(temp_set);
visited.insert(temp_set);
}
set<vector<int>> temp_set2;
vector<int> temp_vec2 = {bigger[0] - 1, bigger[1]};
temp_set2.insert(bigger);
temp_set2.insert(temp_vec2);
if (visited.find(temp_set2) == visited.end())
{
next_positions.insert(temp_set2);
visited.insert(temp_set2);
}
}
if ((smaller[0] != max_len) && board[smaller[0] + 1][smaller[1]] == 0 && board[bigger[0] + 1][bigger[1]] == 0) {
set<vector<int>> temp_set;
vector<int> temp_vec = {smaller[0] + 1, smaller[1]};
temp_set.insert(smaller);
temp_set.insert(temp_vec);
if (visited.find(temp_set) == visited.end())
{
next_positions.insert(temp_set);
visited.insert(temp_set);
}
set<vector<int>> temp_set2;
vector<int> temp_vec2 = {bigger[0] + 1, bigger[1]};
temp_set2.insert(bigger);
temp_set2.insert(temp_vec2);
if (visited.find(temp_set2) == visited.end())
{
next_positions.insert(temp_set2);
visited.insert(temp_set2);
}
}
} else {
if ((smaller[1] != 0) && board[smaller[0]][smaller[1] - 1] == 0 && board[bigger[0]][bigger[1] - 1] == 0) {
set<vector<int>> temp_set;
vector<int> temp_vec = {smaller[0], smaller[1] - 1};
temp_set.insert(smaller);
temp_set.insert(temp_vec);
if (visited.find(temp_set) == visited.end())
{
next_positions.insert(temp_set);
visited.insert(temp_set);
}
set<vector<int>> temp_set2;
vector<int> temp_vec2 = {bigger[0], bigger[1] - 1};
temp_set2.insert(bigger);
temp_set2.insert(temp_vec2);
if (visited.find(temp_set2) == visited.end())
{
next_positions.insert(temp_set2);
visited.insert(temp_set2);
}
}
if ((smaller[1] != max_len) && board[smaller[0]][smaller[1] + 1] == 0 && board[bigger[0]][bigger[1] + 1] == 0) {
set<vector<int>> temp_set;
vector<int> temp_vec = {smaller[0], smaller[1] + 1};
temp_set.insert(smaller);
temp_set.insert(temp_vec);
if (visited.find(temp_set) == visited.end())
{
next_positions.insert(temp_set);
visited.insert(temp_set);
}
set<vector<int>> temp_set2;
vector<int> temp_vec2 = {bigger[0], bigger[1] + 1};
temp_set2.insert(bigger);
temp_set2.insert(temp_vec2);
if (visited.find(temp_set2) == visited.end())
{
next_positions.insert(temp_set2);
visited.insert(temp_set2);
}
}
}
if (smaller[0] != max_len && bigger[0] != max_len && board[smaller[0] + 1][smaller[1]] == 0 && board[bigger[0] + 1][bigger[1]] == 0) {
set<vector<int>> temp_set;
vector<int> temp_vec1 = {smaller[0] + 1, smaller[1]};
vector<int> temp_vec2 = {bigger[0] + 1, bigger[1]};
temp_set.insert(temp_vec1);
temp_set.insert(temp_vec2);
if (visited.find(temp_set) == visited.end())
{
next_positions.insert(temp_set);
visited.insert(temp_set);
}
}
if (smaller[0] != 0 && bigger[0] != 0 && board[smaller[0] - 1][smaller[1]] == 0 && board[bigger[0] - 1][bigger[1]] == 0) {
set<vector<int>> temp_set;
vector<int> temp_vec1 = {smaller[0] - 1, smaller[1]};
vector<int> temp_vec2 = {bigger[0] - 1, bigger[1]};
temp_set.insert(temp_vec1);
temp_set.insert(temp_vec2);
if (visited.find(temp_set) == visited.end())
{
next_positions.insert(temp_set);
visited.insert(temp_set);
}
}
if (smaller[1] != 0 && bigger[1] != 0 && board[smaller[0]][smaller[1] - 1] == 0 && board[bigger[0]][bigger[1] - 1] == 0) {
set<vector<int>> temp_set;
vector<int> temp_vec1 = {smaller[0], smaller[1] - 1};
vector<int> temp_vec2 = {bigger[0], bigger[1] - 1};
temp_set.insert(temp_vec1);
temp_set.insert(temp_vec2);
if (visited.find(temp_set) == visited.end())
{
next_positions.insert(temp_set);
visited.insert(temp_set);
}
}
if (smaller[1] != max_len && bigger[1] != max_len && board[smaller[0]][smaller[1] + 1 ] == 0 && board[bigger[0]][bigger[1] + 1] == 0) {
set<vector<int>> temp_set;
vector<int> temp_vec1 = {smaller[0], smaller[1] + 1};
vector<int> temp_vec2 = {bigger[0], bigger[1] + 1};
temp_set.insert(temp_vec1);
temp_set.insert(temp_vec2);
if (visited.find(temp_set) == visited.end())
{
next_positions.insert(temp_set);
visited.insert(temp_set);
}
}
}
}
void ft_bfs(vector<vector<int>> board, int second, set<set<vector<int>>>& positions) {
if (ft_arrived_goal(positions, second)) {
answer = second;
return ;
}
set<set<vector<int>>> next_positions;
ft_candidate(board, positions, next_positions);
ft_bfs(board, second + 1, next_positions);
}
int solution(vector<vector<int>> board) {
max_len = board.size() - 1;
goal = {max_len, max_len};
set<vector<int>> position;
vector<int> one{0, 0};
vector<int> two{0, 1};
position.insert(one);
position.insert(two);
set<set<vector<int>>> positions;
positions.insert(position);
visited.insert(position);
ft_bfs(board, 0, positions);
return answer;
}
int main() {
vector<vector<int>> board = {
{0, 0, 0, 1, 1},
{0, 0, 0, 1, 0},
{0, 1, 0, 1, 1},
{1, 1, 0, 0, 1},
{0, 0, 0, 0, 0}
};
cout << solution(board) << endl;
}
- 처음에 dfs로 짯다가, 14, 15번 테스트 케이스에서 시간초과가 뜸
- 질문하기 들어가보니 bfs로 풀어야 된다고 함.
- bfs는 재귀가 아니고 queue를 활용한, iteration에 가까워 보였음.
- queue는 쓰지 않았고, set을 사용함... 아무래도 그래서 set 데이터를 2개 따로 들고다님.