본문 바로가기

알고리즘문제풀이

[백준 16441]아기돼지와 늑대

반응형

문제 https://www.acmicpc.net/problem/16441


1)문제 분류

-시뮬레이션


2)문제 해결

- 방법 1) <BFS>늑대의 위치를 큐에 담아 돌릴때 늑대가 움직이는 방향까지 담아서 경로를 3차원으로 체크한다.

 -방법2)<DFS>늑대의 위치를 파악하고, 그 지점에서 재귀타고 2차원으로 체크 한다.

- 늑대가 한번이라도 왔던 곳이라면 safe[][]에 체크한다.

- 문제에서 잘 읽어야 할 부분이 ". 만약 이동한 칸이 빙판이라면 초원을 밟거나 산에 부딪칠 때까지 이동한 방향으로 미끄러집니다. 산에 부딪친 경우 늑대는 빙판 위에 가만히 서있을 수 있고 다시 다른 방향으로 이동할 수 있습니다."  <-이거 못 읽어가지구 몇번 틀렸다 ㅎㅎ ..문제를 잘읽자.!

-safe[][]를 토대로 돼지가 집을 설치할수 있는 곳을 파악해서 출력한다.


<DFS>

#include<iostream>

#include<cstdio>

using namespace std;

int N, M;

char map[102][102];

int safe[102][102];// 한번이라도 늑대가 왔으면 안전한 지역이아님

int xrr[4] = { 0,0,1,-1 };

int yrr[4] = { 1,-1,0,0 };

bool range(int rx, int ry)

{

if (rx<0 || ry<0 || rx>N - 1 || ry>M - 1)return false;

else return true;

}

void DFS(int x, int y)

{

safe[x][y] = true; //안전지대아님을 체크


for (int i = 0; i < 4; i++)

{

int cx = x + xrr[i]; int cy = y + yrr[i];

if (range(cx, cy) == false || safe[cx][cy] == true || map[cx][cy] == '#')continue;

if (map[cx][cy] == 'W' || map[cx][cy] == '.') //초원일때

{

DFS(cx, cy);

}

else //빙판일때

{

while (range(cx, cy) && map[cx][cy] == '+')

{

cx += xrr[i];

cy += yrr[i];

}

if (map[cx][cy] == '#') //산에 부딪혔을때 빙판다른방향으로 이동

{

cx -= xrr[i];

cy -= yrr[i];

}

if (safe[cx][cy]==false) //초원이나, 산에부딪혔을때 다른방향이동

{

DFS(cx, cy);

}

}

}

}

int main()

{

cin >> N >> M;

for (int i = 0; i < N; i++)

{

for (int j = 0; j < M; j++)

{

scanf(" %c",&map[i][j]);

}

}

for (int i = 0; i < N; i++)

{

for (int j = 0; j < M; j++)

{

if (map[i][j] == 'W')DFS(i, j);

}

}

for (int i = 0; i < N; i++)

{

for (int j = 0; j < M; j++)

{

if (safe[i][j] == false && map[i][j] == '.')

{

printf("P");

}

else

{

printf("%c",map[i][j]);

}

}

printf("\n");

}


}




<BFS>

#include<iostream>

#include<vector>

#include<queue>

#include<cstdio>

using namespace std;

int N, M;

char map[102][102];

int chk[102][102][5]; //늑대가 움직이는 경로 체크

int safe[102][102];// 한번이라도 늑대가 왔으면 안전한 지역이아님

int xrr[4] = { 0,0,1,-1 };

int yrr[4] = { 1,-1,0,0 };

typedef struct Data

{

int x, y, dir;

}Data;

vector<Data> wolf;

bool range(int rx, int ry)

{

if (rx<0 || ry<0 || rx>N - 1 || ry>M - 1)return false;

else return true;

}

void BFS(int x, int y, int dir)

{

queue<Data>pq;

pq.push({ x,y,dir });

safe[x][y] = true; //안전지대아님

while (!pq.empty())

{

Data output = pq.front();

pq.pop();

safe[output.x][output.y] = true;//안전지대아님

Data input;

input.dir = output.dir;

input.x = output.x + xrr[input.dir];

input.y = output.y + yrr[input.dir];


if (range(input.x, input.y) && map[input.x][input.y] != '#'&&chk[input.x][input.y][input.dir]==false)

{

chk[input.x][input.y][input.dir] = true;

if (map[input.x][input.y] == '.')

{

for (int d = 0; d < 4; d++)

{

pq.push({ input.x,input.y,d });

}

}

else if (map[input.x][input.y] == '+')

{

int curx = input.x;

int cury = input.y;

while (range(curx, cury) && map[curx][cury] == '+')

{

curx += xrr[input.dir];

cury += yrr[input.dir];

}

if (range(curx, cury))

{

if (map[curx][cury] == '#')

{

curx -= xrr[input.dir];

cury -= yrr[input.dir];

}

for (int d = 0; d < 4; d++)

{

pq.push({ curx,cury,d });

}

}

}

}

}

}

int main()

{

cin >> N >> M;

for (int i = 0; i < N; i++)

{

for (int j = 0; j < M; j++)

{

scanf(" %c", &map[i][j]);

if (map[i][j] == 'W')

{

wolf.push_back({ i,j });

map[i][j] == '.';

}

}

}

for (int i = 0; i < wolf.size(); i++)

{

for (int dir = 0; dir < 4; dir++)

BFS(wolf[i].x, wolf[i].y, dir); //방향

}

for (int i = 0; i < N; i++)

{

for (int j = 0; j < M; j++)

{

if (safe[i][j] == false && map[i][j] == '.')

{

printf("P");

}

else

{

printf("%c",map[i][j]);

}

}

printf("\n");

}


}


반응형

'알고리즘문제풀이' 카테고리의 다른 글

[백준 16235] 나무 재테크  (0) 2019.02.26
[백준 16234]인구 이동  (0) 2019.02.26
[백준 16954] 움직이는 미로 탈출  (1) 2019.02.21
[백준 16918] 봄버맨  (0) 2019.02.20
[백준 16946]벽 부수고 이동하기 4  (0) 2019.02.20