상세 컨텐츠

본문 제목

감시피하기

코딩테스트/DFS,BFS

by 수타. 2023. 6. 15. 21:32

본문

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

 

18428번: 감시 피하기

NxN 크기의 복도가 있다. 복도는 1x1 크기의 칸으로 나누어지며, 특정한 위치에는 선생님, 학생, 혹은 장애물이 위치할 수 있다. 현재 몇 명의 학생들은 수업시간에 몰래 복도로 빠져나왔는데, 복

www.acmicpc.net

문제요약:

학생과 선생이 있을때 중간에 3개의 벽의 놓아 감시를 피할수 있는지 없는지 알아내라

골드5

 

소요시간:

55분

 

1차시도:

import sys
input = sys.stdin.readline
from collections import deque
sys.setrecursionlimit(10000)

n = int(input())

arr = [list(input().split()) for _ in range(n)]

#장애물 설치 
num = 0
piv =0
def make_wall(j,arr):
	global num
	global piv
	if piv: #한번이라도 성공했다면 그이후에 돌려놓은 함수들 다 끝
		return 
	if num==3:
		if watch(): #벽설치가 완료되었다면 확인해보기
			piv =1
			print('YES')
		return 
		
	for i in range(j,n**2): #벽설치를 효율적으로 하기 하나 설치하면 그뒤에서부터 설치가능
		if arr[i//n][i%n]=='X':
			num+=1
			arr[i//n][i%n] = 'O'
			make_wall(i,arr)
			num-=1
			arr[i//n][i%n] = 'X'
			
#find teacher			
teacher = []
for y in range(n):
	for x in range(n):
		if arr[y][x] =='T':
			teacher.append((y,x))
			
dy = [-1,0,1,0]
dx = [0,1,0,-1]

	
def watch():	#한맵에 대하여 선생이 볼 수 있는 모든 경우 보기
	for ky,kx in teacher:
		for i in range(4):
			y = ky
			x = kx
			while True:
				ny = y +dy[i]
				nx = x +dx[i]
				if 0>ny or ny>=n or nx<0 or nx>=n or arr[ny][nx]== 'O': #이걸 구현을 안했었다...
					break
				if arr[ny][nx]== 'S':
					return 0 #학생을 만났다면 더볼필요도 없이 실패
				y = ny
				x = nx
	return 1	 #학생을 안만났으므로 성공

	
make_wall(0,arr)
if not piv:
	print('NO')

 

저번 벽설치 문제 이후라 이제 n개의 벽을 효율적으로 설치하는 법을 알아 구현했고, 다만 이번문제에선 크기가 굉장히 한정적이었기 때문에, itertools를 써도 무방했다.

또한 한 완성된(벽이 모두 설치된) 맵에서 한번이라도 학생을 만났다면 실패 모든경우에서 학생과 마주친적이 없으면 성공이고 성공이라면 다른경우를 할 필요가 없기 때문에 이 논리구조가 조금 헷갈렸어서 해맸지만 그래도 시간내에 해결했다. 다시 풀어서 30분이내에 구현을해봐야 할 필요가 있는 문제 인것같다.    

아 그리고 어디서 많이 해맸는가 생각해봤더니 테두리를 넘어가는것 뿐아니라, 벽을만났을때 멈췄어야 했는데 벽만났을때 멈추는것을 구현을 안했었다... 기본에 충실하자.

'코딩테스트 > DFS,BFS' 카테고리의 다른 글

아이템 줍기  (0) 2023.06.29
리코쳇 로봇  (0) 2023.06.23
무인도 여행  (0) 2023.06.20
연산자 끼워넣기  (0) 2023.06.12
연구소  (0) 2023.06.05

관련글 더보기