백준문제풀이

백준 문제 17070번 파이프 옮기기 1 문제풀이 c++

노가다 김씨 2022. 1. 19. 07:15

https://www.acmicpc.net/problem/17070

 

17070번: 파이프 옮기기 1

유현이가 새 집으로 이사했다. 새 집의 크기는 N×N의 격자판으로 나타낼 수 있고, 1×1크기의 정사각형 칸으로 나누어져 있다. 각각의 칸은 (r, c)로 나타낼 수 있다. 여기서 r은 행의 번호, c는 열의

www.acmicpc.net

문제해석 

bfs 또는 dfs를 통해 문제를 풀 수 있는 문제이다.

파이프가 가로 상태일때 이동후 가능한 결과가 2가지

파이프가 세로 상태일때 이동후 가능한 결과가 2가지

파이프가 대각 상태일때 이동후 가능한 결과가 3가지 존재한다.

 

파이프의 끝 부분을을 기준으로 시작해서 한번 이동후 파이프의 모양,파이프의 끝이 위치하는 행과 열을 총 세쌍을 묶어

큐에 넣어주는것을 반복하고 파이프의 끝이 위치하는 행과 열이 끝에 도달하게 되면 ans값을 1씩 늘린다

다만 여기서 위에 그림에서도 나타나 있듯이 색칠된 부분중에 벽이 존재하지 않아야 하기 때문에

조건문에 이 부분을 추가 로 작성해야 한다.

 

만약 dfs로 푼다면 큐에 넣는 행위를 하지 않고 재귀적 방식으로 푸는 것이 가능하다.

실제로 dfs로 풀면 큐를 사용하지않기때문에 메모리와 시간을 아낄수 있었다.

 

bfs 코드

#include <iostream>
#include <algorithm>
#include <queue>
#include <tuple>
using namespace std;
int ans=0;
queue < tuple<int,int,int> > q; // 가로0 세로 1 대각2
void solve();
bool inside(int ny,int nx);
int a[16][16];
int n;
int main(){
    cout.tie(NULL);
    cin.tie(NULL);
    ios_base::sync_with_stdio(false);
    cin>>n;
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<n; j++)
        {
            cin>>a[i][j];
        }
    }
    q.push({0,0,1});
    solve();
    cout<<ans;
}
bool inside(int ny,int nx)
{
    if(0<=ny&&ny<n&&0<=nx&&nx<n)
    {
        return true;
    }
    else
    {
        return false;
    }
}
void solve(){
    while(!q.empty())
    {
        int flag=get<0>(q.front()); //가로 0 세로 1 대각 2
        int cy=get<1>(q.front());
        int cx=get<2>(q.front());
        q.pop();
        if(cy==n-1&&cx==n-1)
        {
            ans++;
            continue;
        }
        if(flag==0)
        {
            if(inside(cy,cx+1)&&a[cy][cx+1]!=1)
            {
                q.push({0,cy,cx+1});
            }
            if(inside(cy,cx+1)&&a[cy][cx+1]!=1&&inside(cy+1,cx+1)&&a[cy+1][cx+1]!=1&&inside(cy+1,cx)&&a[cy+1][cx]!=1)
            {
                q.push({2,cy+1,cx+1});
            }  
        }
        else if(flag==1)
        {
            if(inside(cy+1,cx)&&a[cy+1][cx]!=1)
            {
                q.push({1,cy+1,cx});
            }
            if(inside(cy+1,cx)&&a[cy+1][cx]!=1&&inside(cy+1,cx+1)&&a[cy+1][cx+1]!=1&&inside(cy,cx+1)&&a[cy][cx+1]!=1)
            {
                q.push({2,cy+1,cx+1});
            }
        }
        else if(flag==2)
        {
            if(inside(cy,cx+1)&&a[cy][cx+1]!=1)
            {
                q.push({0,cy,cx+1});
            }
            if(inside(cy+1,cx)&&a[cy+1][cx]!=1)
            {
                q.push({1,cy+1,cx});
            }
            if(inside(cy,cx+1)&&a[cy][cx+1]!=1&&inside(cy+1,cx)&&a[cy+1][cx]!=1&&inside(cy+1,cx+1)&&a[cy+1][cx+1]!=1)
            {
                q.push({2,cy+1,cx+1});
            }
        }
    }
}

dfs 코드

#include <iostream>
#include <algorithm>
using namespace std;
int ans=0;
void solve(int flag,int cy,int cx);
bool inside(int ny,int nx);
int a[16][16];
int n;
int main(){
    cout.tie(NULL);
    cin.tie(NULL);
    ios_base::sync_with_stdio(false);
    cin>>n;
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<n; j++)
        {
            cin>>a[i][j];
        }
    }
    solve(0,0,1);
    cout<<ans;
}
bool inside(int ny,int nx)
{
    if(0<=ny&&ny<n&&0<=nx&&nx<n)
    {
        return true;
    }
    else
    {
        return false;
    }
}
void solve(int flag,int cy,int cx){
    if(cy==n-1&&cx==n-1)
    {
        ans++;
        return;
    }
    if(flag==0)
    {
        if(inside(cy,cx+1)&&a[cy][cx+1]!=1)
        {
            solve(0,cy,cx+1);
        }
        if(inside(cy,cx+1)&&a[cy][cx+1]!=1&&inside(cy+1,cx+1)&&a[cy+1][cx+1]!=1&&inside(cy+1,cx)&&a[cy+1][cx]!=1)
        {
            solve(2,cy+1,cx+1);
        }  
    }
    else if(flag==1)
    {
        if(inside(cy+1,cx)&&a[cy+1][cx]!=1)
        {
            solve(1,cy+1,cx);
        }
        if(inside(cy+1,cx)&&a[cy+1][cx]!=1&&inside(cy+1,cx+1)&&a[cy+1][cx+1]!=1&&inside(cy,cx+1)&&a[cy][cx+1]!=1)
        {
            solve(2,cy+1,cx+1);
        }
    }
    else if(flag==2)
    {
        if(inside(cy,cx+1)&&a[cy][cx+1]!=1)
        {
            solve(0,cy,cx+1);
        }
        if(inside(cy+1,cx)&&a[cy+1][cx]!=1)
        {
            solve(1,cy+1,cx);
        }
        if(inside(cy,cx+1)&&a[cy][cx+1]!=1&&inside(cy+1,cx)&&a[cy+1][cx]!=1&&inside(cy+1,cx+1)&&a[cy+1][cx+1]!=1)
        {
            solve(2,cy+1,cx+1);
        }
    }
}