#include <string>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
int iVisit[100][100] = {};
void DFS(int iX, int iY, int iFirstX, int iFirstY,
vector<string>& board, int iBendCount, char cDest, vector<pair<char, pair<int, int>>>& sAnswer)
{
// 꺽인 횟수가 2가 넘으면 실패
if (iBendCount >= 2)
return;
if (iX < board.size())
{
if (iY < board[iX].size())
{
// 목적지거나 본인이 아닐 때
if (!iVisit[iX][iY] && board[iX][iY] == cDest && (iFirstX != iX || iFirstY != iY))
sAnswer.push_back({ board[iX][iY], {iX, iY} });
// 갈 수 있거나 본인일 때
else if (!iVisit[iX][iY] && (board[iX][iY] == '.' || board[iX][iY] == cDest))
{
iVisit[iX][iY] += 1;
// 처음 입력할 때
if (!iBendCount)
{
// 사방으로 찾아간다.
DFS(iX + 1, iY, iX, iY, board, iBendCount + 1, cDest, sAnswer);
DFS(iX, iY + 1, iX, iY, board, iBendCount + 1, cDest, sAnswer);
DFS(iX - 1, iY, iX, iY, board, iBendCount + 1, cDest, sAnswer);
DFS(iX, iY - 1, iX, iY, board, iBendCount + 1, cDest, sAnswer);
}
// 처음이 아닐 때
else
{
// 기본 입력과 이전 위치의 차이
int iNextX = iX - iFirstX;
int iNextY = iY - iFirstY;
// X 쪽 이동일 경우
if (iNextX && iBendCount == 1)
{
// 꺽이지 않는 X방향으로 다시 입력 (본인쪽으로는 다시 이동할 필요 X)
DFS(iX + iNextX, iY, iX, iY, board, iBendCount, cDest, sAnswer);
// 꺽인 Y방향 두 곳으로 입력
DFS(iX, iY + 1, iX, iY, board, iBendCount + 1, cDest, sAnswer);
DFS(iX, iY - 1, iX, iY, board, iBendCount + 1, cDest, sAnswer);
}
//Y 축 이동일 경우
else if (iNextY && iBendCount == 1)
{
// 꺽이지 않는 Y방향으로 다시 입력 (본인쪽으로는 다시 이동할 필요 X)
DFS(iX, iY + iNextY, iX, iY, board, iBendCount, cDest, sAnswer);
// 꺽인 X방향 두 곳으로 입력
DFS(iX + 1, iY, iX, iY, board, iBendCount, cDest, sAnswer);
DFS(iX - 1, iY, iX, iY, board, iBendCount, cDest, sAnswer);
}
// X축 이동 + 이미 두 번째 꺽였을 경우 그 쪽 방향으로만 이동
else if (iNextX)
DFS(iX + iNextX, iY, iX, iY, board, iBendCount, cDest, sAnswer);
// Y축 이동 + 이미 두 번째 꺽였을 경우 그 쪽 방향으로만 이동
else if (iNextY)
DFS(iX, iY + iNextY, iX, iY, board, iBendCount, cDest, sAnswer);
}
}
else
return;
}
else
return;
}
else
return;
}
// 전역 변수를 정의할 경우 함수 내에 초기화 코드를 꼭 작성해주세요.
// m -> size
// n -> board[i].size()
string solution(int m, int n, vector<string> board)
{
string answer = "";
vector<char> vecAnswer = {};
vector<pair<char, pair<int, int>>> vecPair = {};
char cAnswer = 'A' - 1;
while (cAnswer != 'Z' + 1)
{
// A부터 늘려가면서 검사
++cAnswer;
for (int i = 0; i < board.size(); ++i)
{
for (int j = 0; j < board[i].size(); ++j)
{
if (board[i][j] == cAnswer)
{
int iPairSize = vecPair.size();
// 시작하기 전에 Visit 초기화
memset(iVisit, 0, sizeof(iVisit));
// 전체 검색
DFS(i, j, i, j, board, 0, board[i][j], vecPair);
// 사이즈가 다르다면 추가했다는 뜻이기 때문에 입력
if (iPairSize < vecPair.size())
vecPair.push_back({ board[i][j], {i,j} });
}
}
}
// vecPair의 사이즈가 있다는 것은 찾았다 -> A부터 다시 검색
if (vecPair.size())
cAnswer = 'A' - 1;
while (vecPair.size())
{
pair<char, pair<int, int>> pPair = vecPair.back();
vecPair.pop_back();
// 찾은 영어 입력
vecAnswer.push_back(pPair.first);
// 찾은 곳 삭제
board[pPair.second.first][pPair.second.second] = '.';
}
}
for (int i = 0; i < board.size(); ++i)
{
for (int j = 0; j < board[i].size(); ++j)
{
// A ~ Z 사이가 있다는 것은 게임을 끝내지 못했다는 뜻 -> 불가능
if (board[i][j] >= 'A' && board[i][j] <= 'Z')
return"IMPOSSIBLE";
}
}
// 똑같은 것들을 다 넣었기 때문에 unique로 실행
vecAnswer.erase(unique(vecAnswer.begin(), vecAnswer.end()), vecAnswer.end());
for (int i = 0; i < vecAnswer.size(); ++i)
{
answer.push_back(vecAnswer[i]);
}
if (answer.size())
return answer;
else
return "IMPOSSIBLE";
}
솔직히 어려운 것보다.. 그냥 뭔가 좀... 귀찮았다고 해야하나 짜증난다고 해야할까...
생각보다 어렵진 않았고 걍 모든 경로를 검사해야되고 A부터 다시 시작해야 한다! 이부분이 좀 어려웠다.
'오늘의 알고리즘' 카테고리의 다른 글
[C++]월간 코드 챌린지 시즌1 3진법 뒤집기(프로그래머스 1레벨) (0) | 2022.02.23 |
---|---|
[C++]월간 코드 챌린지 시즌2 약수의 개수와 덧셈(프로그래머스 1레벨) (0) | 2022.02.23 |
[C++]2017 카카오코드 예선 브라이언의 고민(프로그래머스 3레벨) - 실패 (0) | 2022.02.21 |
[C++]2019 카카오 개발자 겨울 인턴십 튜플 (0) | 2022.02.19 |
[C++]2020 카카오 인턴십 수식 최대화(프로그래머스 2레벨) (0) | 2022.02.18 |