Algorithm/PS

[C++, python] BOJ, 백준 1577 - 도로의 개수

2023. 2. 22. 17:00
목차
  1. 문제 풀이
  2. 공사중인 도로
  3. 정답코드
  4. C++
  5. python
728x90

문제 링크

 

1577번: 도로의 개수

첫째 줄에 도로의 가로 크기 N과 세로 크기 M이 주어진다. N과 M은 100보다 작거나 같은 자연수이고, 둘째 줄에는 공사중인 도로의 개수 K가 주어진다. K는 0보다 크거나 같고, 50보다 작거나 같은 자

www.acmicpc.net

문제 풀이

이 문제는 [0, 0]에서 최단경로로 [N, M]에 도달하기 위한 방법의 수를 구하는 문제이다. 다들 한번씩 경로에 1을 표시해서 총 몇가지의 길이 존재하는지 문제를 풀어봤을 것이다. 이것을 알고리즘으로는 DP로 풀 수 있다.

공사중인 도로

만약 [1, 1]인 지점으로 가기 위해서는 최단거리이므로 무조건 [0, 1] 혹은 [1, 0]을 통과해야 한다.
따라서 [1, 1]까지의 경로는 [0, 1]까지의 경로와 [1, 0]까지의 경로의 합이 될 것이다.
만약 [0, 1] 혹은 [1, 0] 지점부터 [1, 1]지점까지 공사중이라면, 공사중인 지점을 제외한 나머지 경로만 더해질 것이고, 두 경로 모두 공사중이라면, [1, 1]로 오는 경로는 0이 된다.

이 조건을 코드에 반영하면 된다.

정답코드

C++

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>

using namespace std;

#define fast ios_base::sync_with_stdio(false); cin.tie(0), cout.tie(0)
#define ll long long

ll dp[101][101];
int road[101][101][2];
int dy[2]={1,0},dx[2]={0,1};
int N, M, K;

ll sol(int y,int x){
    if(y == N && x == M) return 1;
    ll& ret = dp[y][x];
    if (ret != -1) return ret;
    ret = 0;
    for (int i = 0; i < 2; i++){
        if (!road[y][x][i]){
            int ny = y + dy[i], nx = x + dx[i];
            if (ny <= N && nx <= M) ret += sol(ny, nx);
        }
    }
    return ret;
}

int main() {
    fast;
    cin >> N >> M >> K;
    int cnt = 1;
    while (K--) {
        int a, b, c, d;
        cin >> a >> b >> c >> d;
        if (a > c) swap(a, c);
        else if (b > d) swap(b, d);
        if (a < c) road[a][b][0] = 1;
        else if (b < d) road[a][b][1] = 1;
    }
    memset(dp, -1, sizeof(dp));
    cout << sol(0, 0);
    return 0;
}

python

N, M = map(int, input().split())
K = int(input())
dp = [[0] * (N + 1) for _ in range(M + 1)]
road = []
dp[0][0] = 1
for i in range(K):
    road.append(list(map(int, input().split())))

def check(current, a, b, c, d):
    if current == [a, b, c, d] or current == [c, d, a, b]:
        return True
    else:
        return False

for x in range(M + 1):
    for y in range(N + 1):
        if y > 0:
            for a, b, c, d in road:
                if check([y - 1, x, y, x], a, b, c, d):
                    break
            else:
                dp[x][y] += dp[x][y - 1]
        if x > 0:
            for a, b, c, d in road:
                if check([y, x - 1, y, x], a, b, c, d):
                    break
            else:
                dp[x][y] += dp[x - 1][y]
print(dp[M][N])
728x90

'Algorithm > PS' 카테고리의 다른 글

[C++, python] BOJ, 백준 5569 - 출근 경로  (0) 2023.02.23
[C++, python] BOJ, 2502 - 떡 먹는 호랑이  (0) 2023.02.22
[C++, PYTHON] BOJ, 백준 5582 - 공통 부분 문자열  (0) 2023.02.22
[C++] BOJ, 백준 4883 - 삼각 그래프  (0) 2023.02.21
[C++] BOJ, 백준 2011 - 암호코드  (0) 2023.02.20
  1. 문제 풀이
  2. 공사중인 도로
  3. 정답코드
  4. C++
  5. python
'Algorithm/PS' 카테고리의 다른 글
  • [C++, python] BOJ, 백준 5569 - 출근 경로
  • [C++, python] BOJ, 2502 - 떡 먹는 호랑이
  • [C++, PYTHON] BOJ, 백준 5582 - 공통 부분 문자열
  • [C++] BOJ, 백준 4883 - 삼각 그래프
chanwoong1
chanwoong1
안녕하세요.
250x250
chanwoong1
WOONGTECH
chanwoong1
전체
오늘
어제
  • 분류 전체보기 (231)
    • 42SEOUL (28)
      • Circle0 (1)
      • Circle1 (3)
      • Circle2 (3)
      • Circle3 (2)
      • Circle4 (7)
      • Circle5 (8)
      • Circle6 (4)
    • Algorithm (163)
      • PS (159)
      • Study (4)
    • Blog (5)
    • 우테코 프리코스 (5)
    • Data Science (1)
    • WEB (27)
      • React (18)
      • Recoil (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

인기 글

최근 댓글

최근 글

hELLO · Designed By 정상우.
chanwoong1
[C++, python] BOJ, 백준 1577 - 도로의 개수
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.