[์ฝ”๋“œํŠธ๋ฆฌ ๐Ÿฅ‡3] ๋ฉ”์ด์ฆˆ ๋Ÿฌ๋„ˆ (Python/ํŒŒ์ด์ฌ)

mingssoยท2023๋…„ 9์›” 23์ผ
0

Algorithm

๋ชฉ๋ก ๋ณด๊ธฐ
35/35

1๏ธโƒฃ ๋ฌธ์ œ

https://www.codetree.ai/training-field/frequent-problems/problems/maze-runner?&utm_source=clipboard&utm_medium=text

โ€‹
์˜ฌํ•ด ์ƒ๋ฐ˜๊ธฐ ์‚ผ์„ฑ ์ฝ”ํ…Œ ๊ธฐ์ถœ๋ฌธ์ œ์ด๋‹ค
๋ฌธ์ œ๊ฐ€ ์ •๋ง ์‚ผ์„ฑ์Šค๋Ÿฝ๋‹ค.. ์‹œ๋ฎฌ์‹œ๋ฎฌ
โ€‹
์ด์ฐจ์› ๋ฆฌ์ŠคํŠธ ํšŒ์ „ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋ชป์งœ์„œ ํ’€์ด๋ฅผ ์ฐธ๊ณ ํ•ด์„œ ํ’€์—ˆ๋‹ค๐Ÿฅฒ



2๏ธโƒฃ ํ’€์ด

1. ์ž…๋ ฅ ๋ฐ›๊ธฐ

n, m, k = map(int, input().split())
board = []
for _ in range(n):
    board.append(list(map(int, input().split())))

entry = []   # ์ฐธ๊ฐ€์ž์˜ ์œ„์น˜
for _ in range(m):
    y, x = map(int, input().split())
    entry.append([y-1, x-1])

exit = list(map(int, input().split()))  # ์ถœ๊ตฌ์˜ ์ขŒํ‘œ 
exit[0] -= 1
exit[1] -= 1
answer = 0   # ์ฐธ๊ฐ€์ž๋“ค์˜ ์ด๋™๊ฑฐ๋ฆฌ ํ•ฉ 

์ด๋•Œ ์ขŒํ‘œ๊ฐ€ 1๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ž…๋ ฅ๊ฐ’์—์„œ 1์”ฉ ๋นผ์ค˜์•ผ ํ•œ๋‹ค
์ฒ˜์Œ์— ์ถœ๊ตฌ์˜ ์ขŒํ‘œ์—์„œ 1 ๋นผ๋Š” ๊ฑธ ๋†“์ณค๋‹ค



2. ์ฐธ๊ฐ€์ž ์ด๋™

  • 1์ดˆ๋งˆ๋‹ค ๋ชจ๋“  ์ฐธ๊ฐ€์ž๋Š” ๋™์‹œ์— ํ•œ ์นธ์”ฉ ์ƒํ•˜์ขŒ์šฐ๋กœ ์›€์ง์ธ๋‹ค
  • ์ด๋•Œ, ์›€์ง์ธ ์นธ์€ ํ˜„์žฌ ๋จธ๋ฌผ๋Ÿฌ ์žˆ๋˜ ์นธ๋ณด๋‹ค ์ถœ๊ตฌ๊นŒ์ง€์˜ ์ตœ๋‹จ๊ฑฐ๋ฆฌ(โˆฃx1โˆ’x2โˆฃ+โˆฃy1โˆ’y2โˆฃ)๊ฐ€ ๊ฐ€๊นŒ์›Œ์•ผ ํ•œ๋‹ค
  • ์›€์ง์ผ ์ˆ˜ ์žˆ๋Š” ์นธ์ด 2๊ฐœ ์ด์ƒ์ด๋ผ๋ฉด, ์ƒํ•˜๋กœ ์›€์ง์ด๋Š” ๊ฒƒ์„ ์šฐ์„ ์‹œ
  • ์›€์ง์ผ ์ˆ˜ ์—†์œผ๋ฉด ์›€์ง์ด์ง€ ์•Š์Œ
  • ํ•œ ์นธ์— 2๋ช… ์ด์ƒ์˜ ๋ชจํ—˜๊ฐ€๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Œ
  • ์ฐธ๊ฐ€์ž๋Š” ์ถœ๊ตฌ์— ๋„๋‹ฌํ•˜๋ฉด ์ฆ‰์‹œ ํƒˆ์ถœํ•จ
dy = [-1, 1, 0, 0]   # ์ƒํ•˜์ขŒ์šฐ
dx = [0, 0, -1, 1]

visit = set()   # ์ •์‚ฌ๊ฐํ˜• ์žก์„ ๋•Œ ์‚ฌ์šฉ 
moved = []   # ์ด๋™ํ•œ ์ฐธ๊ฐ€์ž์˜ ์ขŒํ‘œ 
for y, x in entry:
	dist1 = abs(y-exit[0]) + abs(x-exit[1])  # ํ˜„์žฌ ๋จธ๋ฌผ๋Ÿฌ ์žˆ๋Š” ์นธ์˜ ์ถœ๊ตฌ๊นŒ์ง€ ๊ฑฐ๋ฆฌ
	flag = False   # ์›€์ง์ž„ ์—ฌ๋ถ€ ํ‘œ์‹œ 

	for i in range(4):
		ny = y + dy[i]
		nx = x + dx[i]
        
        # ์ฐธ๊ฐ€์ž๋Š” ๋ฒฝ์ด ์—†๋Š” ๊ณณ(๋นˆ์นธ or ์ถœ๊ตฌ)์œผ๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ๋‹ค
        if 0 <= ny < n and 0 <= nx < n and board[ny][nx] == 0:
        	dist2 = abs(ny-exit[0]) + abs(nx-exit[1])  # ์›€์ง์ธ ์นธ์˜ ์ถœ๊ตฌ๊นŒ์ง€์˜ ๊ฑฐ๋ฆฌ
			if dist2 < dist1:  
            	# ์ด๋™ํ•œ ์นธ์ด ์ถœ๊ตฌ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ๋ฆฌ์ŠคํŠธ์— ์ถ”๊ฐ€ํ•ด์คŒ 
				if not (ny == exit[0] and nx == exit[1]):
					moved.append([ny, nx])
					visit.add((ny, nx))
				flag = True
				break 
    
    # ์›€์ง์ผ ์ˆ˜ ์—†์œผ๋ฉด ์›€์ง์ด์ง€ ์•Š์Œ 
	if not flag:
		visit.add((y, x))
		moved.append([y, x])
        
    # ์›€์ง์˜€๋‹ค๋ฉด ์ด๋™๊ฑฐ๋ฆฌ๋ฅผ ๋”ํ•ด์คŒ 
	else:
		answer += 1

์ƒํ•˜๋กœ ์›€์ง์ด๋Š” ๊ฒŒ ์šฐ์„ ์‹œ๋˜๊ธฐ ๋•Œ๋ฌธ์—, ์ƒํ•˜๋กœ ๋จผ์ € ์ด๋™์„ ๊ณ ๋ คํ•ด์ฃผ์—ˆ๋‹ค



3. ๋ฏธ๋กœ ํšŒ์ „

  • ํ•œ ๋ช… ์ด์ƒ์˜ ์ฐธ๊ฐ€์ž์™€ ์ถœ๊ตฌ๋ฅผ ํฌํ•จํ•œ ๊ฐ€์žฅ ์ž‘์€ ์ •์‚ฌ๊ฐํ˜•์„ ์žก์Œ
  • ๊ฐ€์žฅ ์ž‘์€ ํฌ๊ธฐ๋ฅผ ๊ฐ–๋Š” ์ •์‚ฌ๊ฐํ˜•์ด 2๊ฐœ ์ด์ƒ์ด๋ผ๋ฉด, ์ขŒ์ƒ๋‹จ r ์ขŒํ‘œ๊ฐ€ ์ž‘์€ ๊ฒƒ์ด ์šฐ์„ ๋˜๊ณ , ๊ทธ๋ž˜๋„ ๊ฐ™์œผ๋ฉด c ์ขŒํ‘œ๊ฐ€ ์ž‘์€ ๊ฒƒ์ด ์šฐ์„ ๋จ

โ€‹
์ถœ๊ตฌ์˜ ์ขŒํ‘œ์™€ ์ฐธ๊ฐ€์ž์˜ ์œ„์น˜๋ฅผ ์ „๋‹ฌ๋ฐ›์•„, ์ •์‚ฌ๊ฐํ˜•์˜ ์ขŒํ‘œ๋ฅผ ๋ฆฌํ„ดํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค

def find(exit, visit):
    start, end = [0, 0], [0, 0]
    flag = False
	
    # ์ฐธ๊ฐ€์ž์™€ ์ถœ๊ตฌ๋ฅผ ๋ชจ๋‘ ํฌํ•จํ•˜๋ ค๋ฉด ์ •์‚ฌ๊ฐํ˜• ๊ธธ์ด๋Š” 2 ์ด์ƒ์ผ ๊ฒƒ 
    for size in range(2, n):
        for sy in range(0, n-size+1):
            for sx in range(0, n-size+1):
                ey = sy + size - 1
                ex = sx + size - 1
				
                # ์ถœ๊ตฌ๊ฐ€ ์ •์‚ฌ๊ฐํ˜• ๋‚ด๋ถ€์— ํฌํ•จ๋˜๋Š”์ง€ ํ™•์ธ
                if sy <= exit[0] <= ey and sx <= exit[1] <= ex:
                    # ์ฐธ๊ฐ€์ž๊ฐ€ ์ •์‚ฌ๊ฐํ˜• ๋‚ด๋ถ€์— ํฌํ•จ๋˜๋Š”์ง€ ํ™•์ธ
                    for y, x in visit:
                    	# ํ•œ ๋ช…์ด๋ผ๋„ ํฌํ•จ๋˜๋ฉด ์ข…๋ฃŒ
                        if sy <= y <= ey and sx <= x <= ex:
                            start = [sy, sx]
                            end = [ey, ex]
                            flag = True
                            break
                if flag:
                    break
            if flag:
                break
        if flag:
            break
    
    return start[0], start[1], end[0], end[1]

์ขŒํ‘œ๊ฐ€ ์ž‘์€ ๊ฒƒ์ด ์šฐ์„ ๋˜๋Š”๋ฐ, 0๋ถ€ํ„ฐ ํ™•์ธํ•˜๋ฏ€๋กœ ์กฐ๊ฑด์— ๋งŒ์กฑํ•œ๋‹ค



  • ์„ ํƒ๋œ ์ •์‚ฌ๊ฐํ˜•์€ ์‹œ๊ณ„๋ฐฉํ–ฅ์œผ๋กœ 90๋„ ํšŒ์ „ํ•˜๋ฉฐ, ํšŒ์ „๋œ ๋ฒฝ์€ ๋‚ด๊ตฌ๋„๊ฐ€ 1์”ฉ ๊นŽ์ž„

โ€‹
๋‚ด๊ฐ€ ๋ชป ํ‘ผ ๋ถ€๋ถ„์ด๋‹ค..
์ด์ฐจ์› ๋ฆฌ์ŠคํŠธ 90๋„ ํšŒ์ „ ์ฝ”๋“œ๋Š” ์•Œ๊ณ  ์žˆ์—ˆ์ง€๋งŒ, ๋‚ด๊ฐ€ ์•Œ๊ณ  ์žˆ๋Š”๋Œ€๋กœ ์“ฐ๋ฉด ๊ฒฐ๊ณผ๊ฐ€ ์ด์ƒํ–ˆ๋‹คโ˜น๏ธ
์‹œ์ž‘ ์ขŒํ‘œ๋ฅผ (0, 0)์œผ๋กœ ์ด๋™์‹œ์ผœ์ค€ ๋’ค ํšŒ์ „ํ•ด์•ผ ํ–ˆ๋˜ ๊ฒƒ!!!!

sy, sx, ey, ex = find(exit, visit)  # ๊ฐ€์žฅ ์ž‘์€ ์ •์‚ฌ๊ฐํ˜•์˜ ์ขŒํ‘œ 
rotate = copy.deepcopy(board)
m = ey - sy + 1   # ์ •์‚ฌ๊ฐํ˜•์˜ ๊ธธ์ด 

# ์ •์‚ฌ๊ฐํ˜• ํšŒ์ „
for i in range(sy, ey+1):
	for j in range(sx, ex+1):
		oy, ox = i-sy, j-sx   # โญ๏ธ(sy, sx) -> (0, 0)
		ry, rx = ox, m-oy-1
		if board[i][j] > 0:
			rotate[ry+sy][rx+sx] = board[i][j] - 1
		else:
			rotate[ry+sy][rx+sx] = board[i][j]

# ์ •์‚ฌ๊ฐํ˜• ๋‚ด๋ถ€์— ์žˆ๋Š” ์ฐธ๊ฐ€์ž ์ขŒํ‘œ ํšŒ์ „
for i in range(len(moved)):
	if sy <= moved[i][0] <= ey and sx <= moved[i][1] <= ex:
		oy, ox = moved[i][0]-sy, moved[i][1]-sx
		ry, rx = ox, m-oy-1
		moved[i] = [ry+sy, rx+sx]

# ์ถœ๊ตฌ ํšŒ์ „ 
oy, ox = exit[0]-sy, exit[1]-sx
ry, rx = ox, m-oy-1
exit = [ry+sy, rx+sx]

โ€‹
๊ทธ๋ฆฌ๊ณ  ๋˜ ์‹ค์ˆ˜ํ–ˆ๋˜ ๋ถ€๋ถ„์€
์ฐธ๊ฐ€์ž ๋ชจ๋‘ ์ถœ๊ตฌ๋กœ ์ด๋™ํ•ด ํƒˆ์ถœํ•˜๋ฉด ๋ฐ”๋กœ ๋ฐ˜๋ณต๋ฌธ์„ ์ข…๋ฃŒ์‹œ์ผœ์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค
๋‚˜๋Š” ์ฐธ๊ฐ€์ž๋“ค์ด ํƒˆ์ถœํ•œ ์ดํ›„์—๋„ ๋ฏธ๋กœ๋ฅผ ํšŒ์ „์‹œ์ผœ์„œ ์ถœ๊ตฌ ์ขŒํ‘œ๊ฐ€ ๋งˆ์ด๋„ˆ์Šค๊ฐ€ ๋‚˜์™”์—ˆ๋‹ค
๋ฐ˜๋ณต๋ฌธ ์ข…๋ฃŒ ์‹œ์ ์„ ์ƒ๊ฐ์—†์ด ๋ฐ˜๋ณต๋ฌธ ๋งˆ์ง€๋ง‰์— ๋„ฃ์ง€ ์ข€ ๋ง์ž..



3๏ธโƒฃ ์ฝ”๋“œ

import copy

dy = [-1, 1, 0, 0]
dx = [0, 0, -1, 1]

n, m, k = map(int, input().split())
board = []
for _ in range(n):
    board.append(list(map(int, input().split())))

entry = []
for _ in range(m):
    y, x = map(int, input().split())
    entry.append([y-1, x-1])

exit = list(map(int, input().split()))  # ์ถœ๊ตฌ์˜ ์ขŒํ‘œ 
exit[0] -= 1
exit[1] -= 1
answer = 0   # ์ฐธ๊ฐ€์ž๋“ค์˜ ์ด๋™๊ฑฐ๋ฆฌ ํ•ฉ 

def find(exit, visit):
    start, end = [0, 0], [0, 0]
    flag = False

    for size in range(2, n):
        for sy in range(0, n-size+1):
            for sx in range(0, n-size+1):
                ey = sy + size - 1
                ex = sx + size - 1

                if sy <= exit[0] <= ey and sx <= exit[1] <= ex:
                    for y, x in visit:
                        if sy <= y <= ey and sx <= x <= ex:
                            start = [sy, sx]
                            end = [ey, ex]
                            flag = True
                            break
                if flag:
                    break
            if flag:
                break
        if flag:
            break
    
    return start[0], start[1], end[0], end[1]


answer = 0
for t in range(k):
    # ์ฐธ๊ฐ€์ž ์ด๋™ 
    visit = set()
    moved = []
    for y, x in entry:
        dist1 = abs(y-exit[0]) + abs(x-exit[1])  # ํ˜„์žฌ ๋จธ๋ฌผ๋Ÿฌ ์žˆ๋Š” ์นธ์˜ ์ถœ๊ตฌ๊นŒ์ง€ ๊ฑฐ๋ฆฌ
        flag = False   # ์›€์ง์ž„ ์—ฌ๋ถ€ ํ‘œ์‹œ 
        
        for i in range(4):
            ny = y + dy[i]
            nx = x + dx[i]
        
            # ์ฐธ๊ฐ€์ž๋Š” ๋ฒฝ์ด ์—†๋Š” ๊ณณ(๋นˆ์นธ or ์ถœ๊ตฌ)์œผ๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ๋‹ค
            if 0 <= ny < n and 0 <= nx < n and board[ny][nx] == 0:
                dist2 = abs(ny-exit[0]) + abs(nx-exit[1])  # ์›€์ง์ธ ์นธ์˜ ์ถœ๊ตฌ๊นŒ์ง€์˜ ๊ฑฐ๋ฆฌ
                if dist2 < dist1:  
                    # ์ด๋™ํ•œ ์นธ์ด ์ถœ๊ตฌ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ๋ฆฌ์ŠคํŠธ์— ์ถ”๊ฐ€ํ•ด์คŒ 
                    if not (ny == exit[0] and nx == exit[1]):
                        moved.append([ny, nx])
                        visit.add((ny, nx))
                    flag = True
                    break 
        
        # ์›€์ง์ผ ์ˆ˜ ์—†์œผ๋ฉด ์›€์ง์ด์ง€ ์•Š์Œ 
        if not flag:
            visit.add((y, x))
            moved.append([y, x])
        # ์›€์ง์˜€๋‹ค๋ฉด ์ด๋™๊ฑฐ๋ฆฌ๋ฅผ ๋”ํ•ด์คŒ 
        else:
            answer += 1
    
    # ๋ฏธ๋กœ๋ฅผ ํƒˆ์ถœํ–ˆ์„ ๊ฒฝ์šฐ 
    if len(moved) == 0:
        break

    # ๋ฏธ๋กœ ํšŒ์ „ 
    sy, sx, ey, ex = find(exit, visit)
    rotate = copy.deepcopy(board)
    m = ey - sy + 1
    
    for i in range(sy, ey+1):
        for j in range(sx, ex+1):
            oy, ox = i-sy, j-sx
            ry, rx = ox, m-oy-1
            if board[i][j] > 0:
                rotate[ry+sy][rx+sx] = board[i][j] - 1
            else:
                rotate[ry+sy][rx+sx] = board[i][j]
    
    for i in range(len(moved)):
        if sy <= moved[i][0] <= ey and sx <= moved[i][1] <= ex:
            oy, ox = moved[i][0]-sy, moved[i][1]-sx
            ry, rx = ox, m-oy-1
            moved[i] = [ry+sy, rx+sx]

    oy, ox = exit[0]-sy, exit[1]-sx
    ry, rx = ox, m-oy-1
    exit = [ry+sy, rx+sx]

    board = copy.deepcopy(rotate)
    entry = copy.deepcopy(moved)

print(answer)
print(exit[0]+1, exit[1]+1)

profile
๐Ÿฅ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ’ฐ

0๊ฐœ์˜ ๋Œ“๊ธ€