백준 :: 맥주 마시면서 걸어가기<9205번>

혜 콩·2022년 7월 1일
0

알고리즘

목록 보기
28/61

> 문제 <

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

> 아이디어 <

이 문제를 꼭 풀고 싶어서 열심히 머리 굴려봤지만 이미 첫 단추를 잘못 꿴 상태였기 때문에...
장렬하게 실패! bfs 문제가 여럿 그렇듯 dx, dy를 이용해서 풀려고 하니까 너무 산으로 가는 느낌이었다. 그래도 해보자! 해서 백준의 test-case에 대한 답은 잘 나왔지만 백준에서는 RuntimeError(indexError)를 맞이했다... 결국 clone에게로 돌아간 나,,,

각 좌표간의 거리가 (using 맨해튼거리) 1000m 이하면 (50*20m) 상근이는 행복하게 페스티벌에 도착할 수 있다. 이 점을 이용!
현재 좌표와 festival 좌표간의 거리가 1000m 이하라면 'happy' 출력.
IF) 편의점이 있다면, 편의점 갯수만큼 현 좌표(Home or Store)와 편의점의 거리가 1000m 이하라면 queue에 넣어주고 while문을 돌려준다. 이때, 방문하지 않았던 편의점만 가야한다.
각 좌표끼리의 거리가 1000m 를 넘으면 맥주가 떨어지므로 sad를 출력한다.

> 코드 <

# clone (success)
from collections import deque

t = int(input())

def bfs():
    q = deque()
    q.append([home[0], home[1]])
    while q:
        x, y = q.popleft()
        if abs(x - fest[0]) + abs(y - fest[1]) <= 1000:
            print('happy')
            return
        for i in range(n):
            if not visited[i]:
                nx, ny = store[i]
                if abs(x - nx) + abs(y - ny) <= 1000:
                    q.append([nx, ny])
                    visited[i] = 1
    print('sad')
    return

for i in range(t):
    n = int(input())  # 편의점 개수
    home = [int(x) for x in input().split()]
    store = []
    for j in range(n):
        x, y = map(int, input().split())
        store.append([x, y])
    fest = [int(x) for x in input().split()]
    visited = [False for i in range(n)]       # home 제외
    bfs()


# mine (fail)
from collections import deque

t = int(input())        # 테스트 케이스 개수
result = []             # 최종 출력값

def gotoFestival(hx, hy, store, fx, fy):
    queue = deque()
    dx = [1, -1, 0, 0]          # 1 = 50m
    dy = [0, 0, 1, -1]
    sx, sy = [], []
    for i in range(n):
        sx.append(store[i][0])
        sy.append(store[i][1])

    total_dis = abs(fx - hx) + abs(fy - hy)  # festival과 home 간의 거리 = 총 필요한 beer 수
    if total_dis <= 20:
        return 'happy'  # 편의점 들리지 않고 바로 축제로 갈 수 있는 경우
    else:
        xx, yy = hx, hy
        queue.append((xx, yy))
        while queue:
            x, y = queue.popleft()
            visited[x][y] = True
            for i in range(4):
                nx = x + dx[i]
                ny = y + dy[i]
                if 0 <= nx < len(drink) and 0 <= ny < len(drink[0]) and not visited[nx][ny]:
                    drink[nx][ny] = drink[x][y] - 1                 # 맥주 1병씩 drink
                    if n!=0:
                        for j in range(n):
                            if (nx, ny) == (sx[j], sy[j]) and drink[nx][ny] >= 0:       # 편의점 무사히 도착
                                drink[nx][ny] = 20
                    if drink[nx][ny] > 0:
                        queue.append((nx, ny))
                        visited[nx][ny] = True

        if drink[fx][fy] == -1:
            return 'sad'
        else:
            return 'happy'

for _ in range(t):
    store = []
    n = int(input())  # 편의점 개수
    hx, hy = map(int, input().split())
    max_sx, max_sy = 0, 0
    for _ in range(n):
        a, b = map(int, input().split())
        max_sx, max_sy = max(max_sx, a//50), max(max_sy, b//50)             # space 면적 알기 위해 편의점 위치의 가장 긴 가로 세로 구하기
        store.append((a//50, b//50))
    fx, fy = map(int, input().split())
    fx, fy = fx//50, fy//50
    spacelen = max(max_sx, fx)
    spacewid = max(max_sy, fy)
    drink = [[-1]*(spacewid+1) for _ in range(spacelen+1)]       # [[열] * 행]
    visited = [[False] * (spacewid + 1) for _ in range(spacelen + 1)]
    drink[hx][hy] = 20
    
    result.append(gotoFestival(hx, hy, store, fx, fy))

for p in result:
    print(p)

본인 코드는 drink, visited 라는 2차원 공간을 만들었기에, 좌표값으로 음수가 나오면
range를 벗어나서 실패한 듯 하다.

profile
배우고 싶은게 많은 개발자📚

0개의 댓글