문제
리뷰
이동 횟수를 체스판 좌표에 저장하려고 한 방식이 실패했다.
왜냐하면 그 좌표를 지나간 경우가 하나가 아니기 때문이다.
큐에는 이동 좌표를 저장했다. 이동 횟수인 int cnt는 따로 관리했다. 범위 내부이고, 안가본 좌표라면, 체스판 해당 좌표에 cnt를 저장하려고 했다.
int M[M_MAX+1][M_MAX+1]; // 체스판 - 0이 아니면 (미방문시) cnt값을 저장
int cnt = 0;
queue<pair<int,int>> q; //좌표를 저장하는 큐
M[tmpX][tmpY] = cnt;
그래서 큐에 좌표와 cnt를 함께 저장했다.
int M[M_MAX+1][M_MAX+1]; // 체스판 - 방문1 미방문0 만 구분
int cnt = 0;
// q : 현재 좌표{a,b}와 이동 횟수cnt 저장
queue<pair<pair<int,int>,int>> q;
q.push({{a, b}, cnt} ); // 현재좌표와 이동횟수 0 푸시
M[a][b] = 1; // 현재좌표 방문표시
범위 내부이고, 안가본 좌표라면, 이동한 좌표 tmpX tmpY 이동횟수+1 을 큐에 푸시했다.
// 8 방향 확인
for(int i = 0; i < 8; i++){
int tmpX = nx + dx[i]; // 가볼 좌표
int tmpY = ny + dy[i];
if(boundary(tmpX, tmpY)){ // 범위 내부이면
if(M[tmpX][tmpY] == 0){ // 안가봤다면
q.push({ {tmpX, tmpY}, cnt+1} ); // 큐에 이동한 좌표와 이동횟수+1 해서 푸시
M[tmpX][tmpY] = 1; //방문표시
}
}
}
큐에서 pop 했을 때의 좌표가 목적지 좌표라면, 바로 cnt를 return 하게 했다.
어려웠다. 나중에 다시 풀어봐야겠다.
코드
#include <iostream>
#include <queue>
#include <cstring> // memset()
#include <algorithm> // min(), pair STL
#define M_MAX 300
using namespace std;
int M[M_MAX+1][M_MAX+1]; // 체스판
int M_LIMIT; // 체스판 크기
int a,b, x,y; // 현재좌표, 목적좌표
// 8방향
int dx[10] = {1, 2, 2, 1, -2, -1, -2, -1};
int dy[10] = {2, 1, -1, -2, 1, 2, -1, -2};
// M_LIMIT 범위 내에 있는지 확인
bool boundary(int i, int j){
return (i >= 0 && i < M_LIMIT && j >= 0 && j < M_LIMIT) ? 1:0;
}
int BFS(){
int cnt = 0;
// q : 현재 좌표{a,b}와 이동 횟수cnt 저장
queue<pair<pair<int,int>,int>> q;
q.push({{a, b}, cnt} ); // 현재좌표와 이동횟수 0 푸시
M[a][b] = 1; // 현재좌표 방문표시
while(!q.empty()){
pair<pair<int,int>,int> now = q.front();
q.pop();
int nx = now.first.first; // 현재 좌표
int ny = now.first.second;
int cnt = now.second; // 여기까지의 이동횟수 cnt
// 목적지라면 종료
if(nx == x && ny == y){
return cnt;
}
// 8 방향 확인
for(int i = 0; i < 8; i++){
int tmpX = nx + dx[i]; // 가볼 좌표
int tmpY = ny + dy[i];
if(boundary(tmpX, tmpY)){ // 범위 내부이면
if(M[tmpX][tmpY] == 0){ // 안가봤다면
q.push({ {tmpX, tmpY}, cnt+1} ); // 큐에 이동한 좌표와 이동횟수+1 해서 푸시
M[tmpX][tmpY] = 1; //방문표시
}
}
}
}
}
int main(void){
int TC = 0;
cin >> TC;
while(TC--){
cin >> M_LIMIT; // 체스판 크기(범위)
cin >> a >> b >> x >> y; // 현재좌표, 목적좌표
memset(M, 0, sizeof(M)); // 체스판 0초기화
cout << BFS() << '\n';
}
return 0;
}
728x90
'알고리즘 > 백준' 카테고리의 다른 글
Two Dots 백준 16929번 (0) | 2020.09.09 |
---|---|
섬의 개수 백준 4963번 (0) | 2020.09.08 |
사탕게임 백준 3085번 c++ (0) | 2020.09.07 |
후위표기식2 백준 1935번 c++ (0) | 2020.09.07 |
단지 번호 붙이기 백준 2667번 c++ (0) | 2020.09.07 |