From 0a04f3edf02184d08a73660907b708995e36ffd2 Mon Sep 17 00:00:00 2001 From: HyoJin Joo Date: Sun, 27 Apr 2025 04:18:43 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=8A=AC=EB=9D=BC=EC=9E=84=20=EC=9E=A1?= =?UTF-8?q?=EA=B3=A0=20=EB=A0=88=EB=B2=A8=20=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hyoz/code.py" | 35 ++++++ .../hyoz/description.ipynb" | 116 ++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 "02_\354\212\254\353\235\274\354\236\204_\354\236\241\352\263\240_\353\240\210\353\262\250_\354\227\205/hyoz/code.py" create mode 100644 "02_\354\212\254\353\235\274\354\236\204_\354\236\241\352\263\240_\353\240\210\353\262\250_\354\227\205/hyoz/description.ipynb" diff --git "a/02_\354\212\254\353\235\274\354\236\204_\354\236\241\352\263\240_\353\240\210\353\262\250_\354\227\205/hyoz/code.py" "b/02_\354\212\254\353\235\274\354\236\204_\354\236\241\352\263\240_\353\240\210\353\262\250_\354\227\205/hyoz/code.py" new file mode 100644 index 0000000..6a7cdbd --- /dev/null +++ "b/02_\354\212\254\353\235\274\354\236\204_\354\236\241\352\263\240_\353\240\210\353\262\250_\354\227\205/hyoz/code.py" @@ -0,0 +1,35 @@ +def getExpectedEXP(target: int, exp_type: str): + ''' + 누적 경험치를 계산해주는 함수 (반환값: 예상 경험치 누적 합) + + + - target: 경험치를 구하려는 범위 (MONSTER → 슬라임 수 / LEVEL_UP → 레벨) + - exp_type: 경험치 유형 (1. MONSTER: 슬라임 처치 경험치 / 2. LEVEL_UP: 레벨업 필요 경험치) + + ''' + if exp_type == 'MONSTER': + s, l, n = 1, target, target + else: # LEVEL_UP + s, l, n = 0, 2*(target-1), target + + exp = n * (s+l) // 2 # 등차수열 합 공식 + return exp + + +t = int(input()) +for _ in range(t): + killed_monsters = int(input()) + + expected = -1 + user_exp = getExpectedEXP(killed_monsters, 'MONSTER') + + st, en = 1, killed_monsters # 레벨이 몬스터 잡은 수보다 클 수 없으므로 마지막 값으로 설정 + while st <= en: + mid = (st + en) // 2 + expected = getExpectedEXP(mid, 'LEVEL_UP') + + if expected < user_exp: st = mid + 1 + elif expected > user_exp: en = mid - 1 + else: break # 딱 일치하는 경우 + if expected > user_exp: mid = mid - 1 + print(mid) \ No newline at end of file diff --git "a/02_\354\212\254\353\235\274\354\236\204_\354\236\241\352\263\240_\353\240\210\353\262\250_\354\227\205/hyoz/description.ipynb" "b/02_\354\212\254\353\235\274\354\236\204_\354\236\241\352\263\240_\353\240\210\353\262\250_\354\227\205/hyoz/description.ipynb" new file mode 100644 index 0000000..d59c672 --- /dev/null +++ "b/02_\354\212\254\353\235\274\354\236\204_\354\236\241\352\263\240_\353\240\210\353\262\250_\354\227\205/hyoz/description.ipynb" @@ -0,0 +1,116 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "c45eb0a0-a879-415c-97d0-4dbda5a4f7c1", + "metadata": {}, + "source": [ + "# Description" + ] + }, + { + "cell_type": "markdown", + "id": "38df40e1-a6f3-4092-977c-f50acf40e9f7", + "metadata": {}, + "source": [ + "### 문제 개요\n", + "* 문제: [슬라임 잡고 레벨 업!](https://www.acmicpc.net/problem/29717)\n", + "* 문제 요약\n", + " * T번의 테스트 케이스에 대해, N마리의 몬스터(슬라임)를 처치했을 때의 레벨을 구하는 문제이다.\n", + " * 입력\n", + " * 테스트 케이스 **T**: 1 이상 1000 이하의 자연수\n", + " * 처치한 몬스터 수 **N**: 1 이상 10억 이하의 자연수\n", + " * 출력: 몬스터 처치 후 최종 레벨 (정수 값)\n", + "* 주의 사항: 입력 값의 범위가 크기 때문에 타임 에러가 날 가능성이 높다. 등차수열 합 공식과 이진 탐색을 이용하여 최대한 효율성을 높여서 푼다.\n", + "* 문제 유형: 이진 탐색" + ] + }, + { + "cell_type": "markdown", + "id": "81377939-f032-419a-8a10-6e13b1c9ba97", + "metadata": {}, + "source": [ + "# History of Code" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0bf12251-c214-463d-8b07-ff4d22d4ae48", + "metadata": {}, + "outputs": [], + "source": [ + "'''\n", + "시간 복잡도: O(T・log N)\n", + "\n", + "구현 순서\n", + "1. 등차수열 합 공식을 이용하여 슬라임 처치 경험치/레벨업 필요 경험치 구하기: 함수로 구현 → O(1)\n", + "2. 1 이상 N(몬스터 처치 수) 이하 범위를 기준으로 이진 탐색을 수행한다 -> O(log N)\n", + "2-1. mid 값은 범위의 중앙값이며, 이 값을 예상 레벨로 가정하고 필요 경험치를 구한다. \n", + "2-2. 필요 경험치가 현재 획득한 경험치 대비 크면 좌측(작은) 범위, 작으면 우측(큰) 범위를 살펴 본다.\n", + "2-3. 일치할 경우 해당 값을 찾은 것이므로 탐색을 종료한다.\n", + "2-4. 일치하지 않더라도 범위 인덱스가 교차하는 경우 (st>=en) 탐색을 종료한다.\n", + "3. 만약 값이 일치하지 않는 경우, 탐색 종료 시 예상 경험치가 더 높다면 mid 값을 하나 낮춘다. (레벨은 항상 필요 경험치 이상 획득하여야 올라가기 때문)\n", + "4. 위 과정을 테스트 케이스만큼 반복한다. → O(T)\n", + "'''\n", + "\n", + "def getExpectedEXP(cnt_monster, exp_type):\n", + " if exp_type == 'MONSTER':\n", + " s, l, n = 1, cnt_monster, cnt_monster\n", + " else: # LEVEL_UP\n", + " s, l, n = 0, 2*(cnt_monster-1), cnt_monster\n", + " \n", + " exp = n * (s+l) // 2 # 등차수열 합 공식\n", + " return exp\n", + "\n", + "\n", + "t = int(input())\n", + "for _ in range(t):\n", + " killed_monsters = int(input())\n", + "\n", + " expected = -1\n", + " user_exp = getExpectedEXP(killed_monsters, 'MONSTER')\n", + " \n", + " st, en = 1, killed_monsters # 레벨이 몬스터 잡은 수보다 클 수 없으므로 마지막 값으로 설정\n", + " while st <= en:\n", + " mid = (st + en) // 2\n", + " expected = getExpectedEXP(mid, 'LEVEL_UP')\n", + "\n", + " if expected < user_exp: st = mid + 1 \n", + " elif expected > user_exp: en = mid - 1\n", + " else: break # 딱 일치하는 경우\n", + " if expected > user_exp: mid = mid - 1\n", + " print(mid)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4031b0a8-dc9a-431c-90f6-c99806d0d274", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.13" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}