문제 링크 : programmers.co.kr/learn/courses/30/lessons/1836#
<전체적인 알고리즘>
1. 존재하는 알파벳과 알파벳의 위치를 map에 저장한다.
2. map은 자동 오름차순 정렬이 되니 차례대로 탐색하며 제거가능한 알파벳이 있나 확인
- 알파벳 제거하는 알고리즘은 백트래킹이나 bfs쓰면 된다. (자세한 알고리즘은 코드의 주석 참고)
3. 전부 제거하거나 더이상 제거 못할때 까지 2를 반복
<전체 코드>
#include<iostream>
#include <string>
#include <vector>
#include<queue>
#include<map>
#include<algorithm>
using namespace std;
int m;
int n;
vector<string> board;
bool check[102][102];
int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
map<char,pair<int,int>> pos;
map<char,pair<int,int>>::iterator iter;
class ins
{
public:
int x,y,turn_count,d;
ins(int x, int y, int turn_count,int d)
{
this->x=x;
this->y=y;
this->turn_count=turn_count;
this->d=d;
}
};
vector<int> bfs(int startx, int starty) //제거 가능한 타일 목적지 위치 반환
{
fill(&check[0][0], &check[99][100], 3);
char alpha = board[startx][starty];
queue<ins> q;
q.push(ins(startx, starty, 0, -1));
check[startx][starty] = 0;
bool isfirst = true;
while (!q.empty())
{
int x = q.front().x;
int y = q.front().y;
int turn_count = q.front().turn_count; //꺾은 횟수
int d = q.front().d; //현재 진행방향
q.pop();
if (!isfirst&&board[x][y] == alpha) // 목적지 알파벳 찾으면 반환
{
vector<int> v{ x,y };
return v;
}
isfirst = false;
for (int dd = 0; dd < 4; dd++)
{
int tmp = turn_count;
int nextx = x + dir[dd][0];
int nexty = y + dir[dd][1];
if (nextx < 0 || nexty < 0 || nextx >= m || nexty >= n)continue;
if (!(board[nextx][nexty]=='.'||board[nextx][nexty]==alpha))continue;
if (d != -1 && d != dd) tmp++; //꺾으면 tmp증가
if (tmp > 1)continue; //2번이상 꺾으면 패스
if (check[nextx][nexty]<tmp)continue;
check[nextx][nexty] = tmp;
q.push(ins(nextx, nexty, tmp, dd));
}
}
vector<int> v;
return v;
}
// 전역 변수를 정의할 경우 함수 내에 초기화 코드를 꼭 작성해주세요.
string solution(int m2, int n2, vector<string> board2) {
m=m2;
n=n2;
board=board2;
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(board[i][j]>='A'&&board[i][j]<='Z')
{
char c = board[i][j];
pos[c]=make_pair(i,j); //map에 알파벳 위치 저장
}
}
}
string answer = "";
while(1)
{
bool isfinish=true;
for(iter=pos.begin();iter!=pos.end();iter++) //존재하는 알파벳순으로 확인하기
{
pair<int,int> p = iter->second;
vector<int> v = bfs(p.first,p.second); //목적지 위치 반환
if(v.size()==0)continue; //벡터가 비어있으면 제거 불가능
isfinish=false;
char c = board[p.first][p.second];
answer+=c;
board[p.first][p.second]='.'; //시작위치 알파벳 제거
board[v[0]][v[1]]='.'; //목적지 위치 알파벳 제거
pos.erase(iter); // 제거했으니 map에서도 제거
break;
}
if(pos.size()==0)break; //전부 제거했으면 종료
if(isfinish)return "IMPOSSIBLE"; //더이상 제거 안되면 impossible반환
}
return answer;
}
궁금하신 점은 댓글에 남겨주시면 답변드리겠습니다.
반응형
'프로그래머스 코딩 문제 > 카카오 기출문제' 카테고리의 다른 글
[프로그래머스] GPS (2017 카카오코드 본선) (0) | 2020.11.04 |
---|---|
[프로그래머스] 보석 쇼핑 (2020 카카오 인턴십) (0) | 2020.11.01 |
[프로그래머스] 방금그곡 (2018 KAKAO BLIND RECRUITMENT) (0) | 2020.09.10 |
[프로그래머스] 매칭 점수 (2019 KAKAO BLIND RECRUITMENT) (level 3) (0) | 2020.09.06 |
[프로그래머스] 기둥과 보 설치 (2020 KAKAO BLIND RECRUITMENT) (level 3) (0) | 2020.09.03 |