일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 수 정렬하기2
- 12969
- knuth_optimization
- 오픽
- 파이썬
- 컴공
- 웹 페이지 입문
- HTML
- 더하기 시리즈
- 스택
- DFS
- ENFJ
- BFS
- Python
- 백준풀이
- 구현
- 백준
- Greedy
- 정규 표현식 #문자열
- 다이나믹 프로그래밍
- 11066
- 정렬
- DP
- 2
- 오늘의 계획
- 백트래킹
- 브루트포스
- 코딩
- 3
- 1
- Today
- Total
코딩하는 Fug
17070 파이프 옮기기 1 본문
https://www.acmicpc.net/problem/17070
#dp
17070번: 파이프 옮기기 1
유현이가 새 집으로 이사했다. 새 집의 크기는 N×N의 격자판으로 나타낼 수 있고, 1×1크기의 정사각형 칸으로 나누어져 있다. 각각의 칸은 (r, c)로 나타낼 수 있다. 여기서 r은 행의 번호, c는 열의
www.acmicpc.net
#17070 파이프 옮기기 1
#내코드 ( 시간초과 )
from sys import stdin
input=stdin.readline
#스탠다드 입력
def solution(d,r,c):
global answer
if r==n-1 and c==n-1:
answer+=1
'''
1. d는 이전의 파이프 방향
2. 파이프의 조건 대각선일때 [y+1][x] [y+1][x+1] [y][x+1] 다 비어져 있고 그냥 일자로 갈때는 방향에 따라 거기에 없어야 하며
3. n-1값을 넘어서는 안된다.
4. 예를 들어 d=1 row 이면 house[y][x+1]=1 해주고 돌리고 다음에 0으로 바꿔줘야 다음으로 넘어갈 수 있음
'''
if d==0:
if not (r==n-1 or c==n-1) and not (house[c+1][r+1] or house[c+1][r] or house[c][r+1]):
house[c+1][r+1]=1
solution(0,r+1,c+1)
house[c+1][r+1]=0
if r!=n-1 and not house[c][r+1]:
house[c][r+1]=1
solution(1,r+1,c)
house[c][r+1]=0
if c!=n-1 and not house[c+1][r]:
house[c+1][r]=1
solution(2,r,c+1)
house[c+1][r]=0
if d==1:
if not (r==n-1 or c==n-1) and not (house[c+1][r+1] or house[c+1][r] or house[c][r+1]):
house[c+1][r+1]=1
solution(0,r+1,c+1)
house[c+1][r+1]=0
if r!=n-1 and not house[c][r+1]:
house[c][r+1]=1
solution(1,r+1,c)
house[c][r+1]=0
if d==2:
if not (r==n-1 or c==n-1) and not (house[c+1][r+1] or house[c+1][r] or house[c][r+1]):
house[c+1][r+1]=1
solution(0,r+1,c+1)
house[c+1][r+1]=0
if c!=n-1 and not house[c+1][r]:
house[c+1][r]=1
solution(2,r,c+1)
house[c+1][r]=0
n=int(input())
house=[list(map(int,input().split())) for i in range(n)]
house[0][0]=1
house[0][1]=1
answer=0
solution(1,1,0)
if answer:
print(answer)
else:
print(0)
#진짜 해석느낌으로 적어봤는데 시간초과가 나왔다 하하하핳ㅎ. 절망적이게도 답지를 보게 되었다.
#내 생각은 하나하나 길을 따라가는 것이였다 하지만 이는 dp를 사용한것과는 시간이 차원이 다르기에 틀렸다는걸 이미 #알고있었고, dp를 사용해서 풀려고 해도 생각이 나지 않아 힘들었다 고로 답지행..
#답지
# 17070 파이프 옮기기 1 dp 사용
from sys import stdin
input=stdin.readline
# 스탠다드 인풋
n=int(input())
pipe=[list(map(int,input().split())) for i in range(n)]
# 기본 입력
dp=[[[0]*3 for i in range(n)] for i in range(n)]
# dp 생성 가로 세로 대각선
dp[0][1][0]=1
dp[0][0][0]=1
# dp 초기값 처음에 0 0 과 0 1 이 연결 되어있으므로
def up_pipe(x,y):
try:
if pipe[y][x] or pipe[y-1][x]:
raise
up=dp[y-1][x]
except:
up=None
return up
# 위쪽 파이프 탐색과 현재 파이프 탐색 여기서 중요한건 이미 파이프를 보내놓고 이전것을 생각한다는 것이다. 이것이
# 이 dp의 핵심이다.
def left_pipe(x,y):
try:
if pipe[y][x] or pipe[y][x-1]:
raise
left=dp[y][x-1]
except:
left=None
return left
# 왼쪽 파이프와 현재 파이프 탐색
def diagonal_pipe(x,y):
try:
if pipe[y][x] or pipe[y-1][x-1] or pipe[y][x-1] or pipe[y-1][x]:
raise
diagonal=dp[y-1][x-1]
except:
diagonal=None
return diagonal
# 대각선으로 오기 위해서는 위쪽 왼쪽 대각선뒤 다 확인해야됨.
for y in range(n):
# 0 0 , 0 1로 시작 고로 y시작은 0
for x in range(2,n):
# 1부터 시작하고 가로로 시작했기 때문에 어떻게 해도 2부터 시작함 ( 대각선, 가로)
if pipe[y][x]==1:
continue
# y x가 벽일경우 스킵하고 다음으로
up=up_pipe(x,y)
if up:
dp[y][x][1]=up[2]+up[1]
#세로로 파이프를 두려면 이전것이 대각선, 세로로 끝났어야 한다.
left=left_pipe(x,y)
if left:
dp[y][x][0]=left[0]+left[2]
#위와 같음
diagonal=diagonal_pipe(x,y)
if diagonal:
dp[y][x][2]=diagonal[2]+diagonal[1]+diagonal[0]
#대각선은 다 가능
print(sum(dp[n-1][n-1]))
#생각하니깐 너무 간단해서 화가 난다. 생각을 잘해야된다. y와 x 그리고 3개의 인덱스를 이용해서 dp를 작성한 후 약간 피보나치처럼 처리를 해주는 간단한 문제였다.
'백준풀이-python' 카테고리의 다른 글
1303 전쟁 - 전투 (0) | 2021.09.01 |
---|---|
1260 DFS와 BFS (0) | 2021.09.01 |
1062 가르침 (0) | 2021.08.25 |
1038 감소하는 수 (0) | 2021.08.20 |
2667 단지번호붙이기 (0) | 2021.08.17 |