강의

멘토링

로드맵

Inflearn brand logo image

인프런 커뮤니티 질문&답변

HELLO님의 프로필 이미지
HELLO

작성한 질문수

10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트

3-D와 반례

3-D 뭐가 문제인지 잘 모르겠습니다..

작성

·

142

0

안녕하세요 선생님

강의 잘 보고 있습니다.

아래의 코드가 왜 탈락하는 지 잘 모르겠습니다..ㅜ

/******************************************************************************

Welcome to GDB Online.
GDB online is an online compiler and debugger tool for C, C++, Python, Java, PHP, Ruby, Perl,
C#, OCaml, VB, Swift, Pascal, Fortran, Haskell, Objective-C, Assembly, HTML, CSS, JS, SQLite, Prolog.
Code, Compile, Run and Debug online from anywhere in world.

*******************************************************************************/
#include <iostream>
#include <queue>
#include <vector>
#include <string>
#include <cmath>

std::string map[1000];
bool visited[1000][1000];
bool visitedFire[1000][1000];
int personMap[1000][1000];
int fireMap[1000][1000];
int exitY, exitX;
int cnt;

#define INF 420000000

void bfsFire(const int y, const int x, const int R, const int C)
{
    std::queue<std::pair<int, int>> que;
    que.push({y, x});
    visitedFire[y][x] = true;
    
    int newX, newY, currX, currY;
    int dx[4] = {1, -1, 0, 0};
    int dy[4] = {0, 0, 1, -1};
    
    while(que.empty() != true)
    {
        currY = que.front().first;
        currX = que.front().second;
        que.pop();
        for(int  i = 0; i < 4; ++i)
        {
            newY = currY + dy[i];
            newX = currX + dx[i];
            if (newX >= 0 && newX < C && newY >= 0 && newY < R && !visitedFire[newY][newX] && map[newY][newX] != '#')
            {
                que.push({newY, newX});
                fireMap[newY][newX] = std::min(fireMap[currY][currX] + 1, fireMap[newY][newX]);
                visitedFire[newY][newX] = true;
            }
        }
    }
}

void bfs(const int y, const int x, const int R, const int C)
{
    std::queue<std::pair<int, int>> que;
    que.push({y, x});
    visited[y][x] = true;
    
    int newX, newY, currX, currY;
    int dx[4] = {1, -1, 0, 0};
    int dy[4] = {0, 0, 1, -1};
    
    while(que.empty() != true)
    {
        currY = que.front().first;
        currX = que.front().second;
        que.pop();
        if (currY == R - 1 || currX == C - 1)
        {
            cnt = personMap[currY][currX];
            return;
        }
        for(int  i = 0; i < 4; ++i)
        {
            newY = currY + dy[i];
            newX = currX + dx[i];
            if (newX >= 0 && newX < C && newY >= 0 && newY < R && !visited[newY][newX] && map[newY][newX] == '.')
            {
                if (fireMap[newY][newX] > personMap[currY][currX] + 1)
                {
                    que.push({newY, newX});
                    personMap[newY][newX] = personMap[currY][currX] + 1;    
                }
                visited[newY][newX] = true;
            }
        }
    }
}

bool isPossible(int R, int C)
{
    for (int i = 0; i < R; ++i)
    {
        if (personMap[i][0] < fireMap[i][0]) return true;
        if (personMap[i][C - 1] < fireMap[i][C - 1]) return true;
    }
    
    for (int i = 0; i < C; ++i)
    {
        if (personMap[0][i] < fireMap[0][i]) return true;
        if (personMap[R - 1][i] < fireMap[R - 1][i]) return true;
    }
    
    return false;
}

int main()
{
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
    
    int R, C;
    
    std::cin >> R >> C;
    std::vector<std::pair<int, int>> fire;
    exitX = C;
    exitY = R;
    int y, x;
    
    std::fill(&fireMap[0][0], &fireMap[999][1000], INF);
    for(int i = 0; i < R; ++i)
    {
        std::cin >> map[i];
        for (int j = 0; j < C; ++j)
        {
            if (map[i][j] == 'J') 
            {
                y = i;
                x = j;
                personMap[i][j] = 1;
            }
            else if (map[i][j] == 'F')
            {
                fireMap[i][j] = 1;
                fire.push_back({i, j});
            }
        }
    }
    
    bfs(y, x, R, C);
    for(int i = 0; i < fire.size(); ++i)
        bfsFire(fire[i].first, fire[i].second, R, C);
    
    if (!isPossible(R, C)) cnt = 0;
    
    if(cnt == 0)
    {
        std::cout << "IMPOSSIBLE" << std::endl;
    }
    else
    {
        std::cout << cnt << std::endl;
    }
    
    
    

    return 0;
}

답변 1

0

큰돌님의 프로필 이미지
큰돌
지식공유자

안녕하세요 HELLLO님ㅎㅎ

탈출조건

        if (currY == R - 1 || currX == C - 1) // 0일 때도 확인해야. 

 

방문처리 순서


                    personMap[newY][newX] = personMap[currY][currX] + 1;    
                    // 이 때 visited를 true설정해야.
                }
                visited[newY][newX] = true;

 

순서


    // 불 bfs -> 인간 이동해야. 그리고 불은 한번에 bfs로 해야. 
    bfs(y, x, R, C);
    for(int i = 0; i < fire.size(); ++i)
        bfsFire(fire[i].first, fire[i].second, R, C);

그리고 불은 INF로 초기화를 해야 합니다.

해당 부분 참고해서 다시 짜보시겠어요?

그리고 그 다음에 제가 다듬은 코드를 보시면 됩니다.

제가 HELLO님 코드를 다듬은 코드는 다음과 같습니다.

#include <iostream>
#include <queue>
#include <vector>
#include <string>
#include <algorithm>
#include <climits>

#define INF INT_MAX

std::string map[1000];
bool visited[1000][1000];
bool visitedFire[1000][1000];
int personMap[1000][1000];
int fireMap[1000][1000];
int exitY, exitX;
int cnt;

void bfsFire(const int R, const int C)
{
    std::queue<std::pair<int, int>> que;
     
    for (int i = 0; i < R; ++i) {
        for (int j = 0; j < C; ++j) {
            if (map[i][j] == 'F') {
                que.push({i, j});
                visitedFire[i][j] = true;
                fireMap[i][j] = 0;
            }
        }
    }

    int newX, newY, currX, currY;
    int dx[4] = {1, -1, 0, 0};
    int dy[4] = {0, 0, 1, -1};
    
    while (!que.empty()) {
        currY = que.front().first;
        currX = que.front().second;
        que.pop();
        for (int i = 0; i < 4; ++i) {
            newY = currY + dy[i];
            newX = currX + dx[i];
            if (newX >= 0 && newX < C && newY >= 0 && newY < R && !visitedFire[newY][newX] && map[newY][newX] != '#') {
                que.push({newY, newX});
                fireMap[newY][newX] = fireMap[currY][currX] + 1;
                visitedFire[newY][newX] = true;
            }
        }
    }
}

int bfs(const int y, const int x, const int R, const int C)
{
    std::queue<std::pair<int, int>> que;
    que.push({y, x});
    visited[y][x] = true;
    personMap[y][x] = 0;
    
    int newX, newY, currX, currY;
    int dx[4] = {1, -1, 0, 0};
    int dy[4] = {0, 0, 1, -1};
    
    while (!que.empty()) {
        currY = que.front().first;
        currX = que.front().second;
        que.pop();
         
        if (currY == 0 || currY == R - 1 || currX == 0 || currX == C - 1) {
            return personMap[currY][currX] + 1; 
        }
        
        for (int i = 0; i < 4; ++i) {
            newY = currY + dy[i];
            newX = currX + dx[i];
            if (newX >= 0 && newX < C && newY >= 0 && newY < R && !visited[newY][newX] && map[newY][newX] == '.') {
                if (fireMap[newY][newX] > personMap[currY][currX] + 1) {
                    que.push({newY, newX});
                    personMap[newY][newX] = personMap[currY][currX] + 1;
                    visited[newY][newX] = true;
                }
            }
        }
    }
    
    return -1; 
}

int main()
{
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
    int R, C;
    std::cin >> R >> C;
    
    int startY, startX;
    
    for (int i = 0; i < R; ++i) {
        std::cin >> map[i];
        for (int j = 0; j < C; ++j) { 
            fireMap[i][j] = INF;
            if (map[i][j] == 'J') {
                startY = i;
                startX = j;
                personMap[i][j] = 0;
            }
        }
    }
    
    bfsFire(R, C);
    int result = bfs(startY, startX, R, C);
    
    if (result == -1) {
        std::cout << "IMPOSSIBLE" << std::endl;
    } else {
        std::cout << result << std::endl;
    }
    
    return 0;
}

 


또 질문 있으시면 언제든지 질문 부탁드립니다.

좋은 수강평과 별점 5점은 제게 큰 힘이 됩니다. :)

감사합니다.

강사 큰돌 올림.


HELLO님의 프로필 이미지
HELLO

작성한 질문수

질문하기