디펜스 게임

2024. 7. 15. 14:34· 알고리즘/프로그래머스
728x90
 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

쉽지 않았던 문제.

처음에는 이거 백트래킹으로 풀어야하나? 라는 생각이 들어서 백트래킹으로 코드를 한 번 작성해봤다.

 


첫 풀이 -> 백트래킹 사용 -> 오답 및 시간초과

 

import sys
sys.setrecursionlimit(10**6)

maxim = 0

def backTracking(n, k, enemy, answer):
    global maxim
    if n == 0:
        return answer
    if n < 0:
        return answer - 1
    if len(enemy) == 0:
        return answer
    
    # 무적권을 쓰지 않고 병사로 막는 경우
    maxim = max(backTracking(n-enemy[0], k, enemy[1:], answer + 1), maxim)
    n += enemy[0]
    answer -= 1
    # 무적권을 쓰는 경우
    maxim = max(backTracking(n, k-1, enemy[1:], answer + 1), maxim)
    
    return maxim


def solution(n, k, enemy):
    answer = 0
    
    if k >= len(enemy):
        return len(enemy)
    if n >= sum(enemy):
        return len(enemy)
    
    answer = backTracking(n, k, enemy, 0)
    return answer

 

시간초과 및 오답이 나오는 걸 보고 이건 아니다 라는 생각이 들었다.

그럼 도대체 어떤 자료구조나 알고리즘을 사용해서 풀어야할지 감이 잡히지 않았다.

순서대로 데이터를 받아야 하니까 라운드의 적수가 큰 수로 정렬해서 푸는 건 아니었고, 뭘 써야할 지 모르겠어서 풀이를 참고해서 풀었다.

 


풀이 코드 -> 우선순위 큐 사용

 

import heapq # 우선순위 큐 사용

def solution(n, k, enemy):
    answer = 0
    
    # 만약 사용가능한 무적권의 횟수가 전체 라운드 수 이상이거나, 준호가 처음 가지고 있는 병사의 수가 전체 적 수 이상이라면 모든 라운드를 막을 수 있으므로 enemy의 길이 리턴
    if k >= len(enemy) or n >= sum(enemy):
        return len(enemy)
    
    # 무적권의 횟수만큼 일단 우선순위 큐에 넣는다.
    q = enemy[:k]
    heapq.heapify(q)
    
    answer = k
    index = k
    
    # 준호가 가지고 있는 병사의 수가 0보다 큰 경우에 반복문을 돌린다.
    while n > 0:
        # 만약 index가 초과하는 경우는 모든 라운드를 막아낼 수 있는 경우이므로 answer를 리턴
        if index >= len(enemy):
            return answer
        
        # 큐에 들어 있던 한 라운드의 적 수에서 가장 작은 적 수인 q_min_enemy
        q_min_enemy = heapq.heappop(q)
        # 만약 현재 라운드의 적 수가 큐에 들어 있던 가장 적은 적수보다 크다면, 현재 라운드를 큐에 넣고(무적권을 사용), 큐에 들어 있던 가장 적은 적수는 준호의 병사로 막는다.
        if enemy[index] > q_min_enemy:
            heapq.heappush(q, enemy[index])
            n -= q_min_enemy
        # 반대라면 큐에 들어 있던 가장 적은 적수를 다시 큐에 넣고(무적권을 사용), 현재 라운드를 준호의 병사로 막는다.
        else:
            heapq.heappush(q, q_min_enemy)
            n -= enemy[index]
        
        # index, answer 추가
        index += 1
        answer += 1
        
    # 만약 n이 0이면 answer 리턴
    if n == 0:
        return answer
    # n이 0보다 작으면 그 전라운드 까지 막을 수 있는 것이므로 answer - 1 리턴
    else:
        return answer - 1

 

우선순위 큐를 사용해서 푸는 문제였다.

우선순위 큐에 k 길이 만큼의 각 라운드별 적수를 넣고, 앞에서부터 차례대로 라운드 별 적수를 확인하며 현재 확인하는 라운드별 적수보다 큐에 들어 있는 가장 적은 라운드별 적수가 작다면 현재 확인하는 라운드별 적수를 큐에 넣고, 원래 큐에 들어 있던 라운드별 가장 적은 적수는 준호가 가지고 있는 병사를 통해 처리해주면 된다.


 

우선순위 큐의 새로운 활용법을 알 수 있는 문제였다.

728x90

'알고리즘 > 프로그래머스' 카테고리의 다른 글

우박수열 정적분  (1) 2024.07.19
멀쩡한 사각형  (0) 2024.07.17
야근 지수  (0) 2024.07.10
하노이의 탑  (0) 2024.07.09
가장 큰 정사각형 찾기  (0) 2024.07.09
'알고리즘/프로그래머스' 카테고리의 다른 글
  • 우박수열 정적분
  • 멀쩡한 사각형
  • 야근 지수
  • 하노이의 탑
happenundo
happenundo
happenundo
2023~ 개발블로그
happenundo
전체
오늘
어제
  • 분류 전체보기 (207)
    • TIL (3)
    • 알고리즘 (188)
      • 프로그래머스 (47)
      • 백준 (69)
      • 파이썬 문법 (11)
      • 이것이 코딩테스트다 (46)
      • 알고리즘 노트 (6)
      • SQL (8)
    • Spring (4)
      • Spring 입문 (2)
      • 개인 프로젝트 (1)
      • 인텔리제이 (1)
    • CS (8)
      • DB (2)
      • 네트워크 (1)
      • 그외 (5)
    • ~2022 (1)
    • etc (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • distinct
  • 정렬
  • DP
  • deepcopy
  • 이것이코딩테스트다
  • 알고리즘
  • 동적프로그래밍
  • 그리디
  • 프로그래머스
  • 완전탐색
  • 백트래킹
  • 플로이드워셜
  • 이코테
  • CS
  • sql
  • dfs
  • 파이썬
  • 최단거리
  • BinarySearch
  • 구현
  • 우선순위큐
  • 다이나믹프로그래밍
  • 괄호변환
  • 다익스트라
  • 재귀
  • 이진탐색
  • 스택
  • 백준
  • 큐
  • BFS

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
happenundo
디펜스 게임
상단으로

티스토리툴바

단축키

내 블로그

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

블로그 게시글

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

모든 영역

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

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