Skip to content

Commit

Permalink
Updates
Browse files Browse the repository at this point in the history
  • Loading branch information
phnml1 committed Nov 16, 2024
1 parent 7c73a39 commit d026020
Show file tree
Hide file tree
Showing 100 changed files with 60 additions and 62 deletions.
2 changes: 1 addition & 1 deletion 404.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/_next/static/media/a15f2fce4b98b461-s.p.woff2" as="font" type="font/woff2" crossorigin="anonymous" data-next-font="size-adjust"/><link rel="preload" href="/_next/static/media/3d9ea938b6afa941-s.p.woff2" as="font" type="font/woff2" crossorigin="anonymous" data-next-font="size-adjust"/><link rel="preload" href="/_next/static/media/ee285b05ac47a625-s.p.woff2" as="font" type="font/woff2" crossorigin="anonymous" data-next-font="size-adjust"/><link rel="preload" href="/_next/static/media/1de9c871cd3a3669-s.p.woff2" as="font" type="font/woff2" crossorigin="anonymous" data-next-font="size-adjust"/><link rel="preload" href="/_next/static/media/bf54e24be5d8358f-s.p.woff2" as="font" type="font/woff2" crossorigin="anonymous" data-next-font="size-adjust"/><link rel="preload" href="/_next/static/media/02701f268eb7de16-s.p.woff2" as="font" type="font/woff2" crossorigin="anonymous" data-next-font="size-adjust"/><link rel="preload" href="/_next/static/css/23abc12e276fc5ef.css" as="style" crossorigin=""/><link rel="stylesheet" href="/_next/static/css/23abc12e276fc5ef.css" crossorigin="" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" crossorigin="" nomodule="" src="/_next/static/chunks/polyfills-c67a75d1b6f99dc8.js"></script><script src="/_next/static/chunks/webpack-59c5c889f52620d6.js" defer="" crossorigin=""></script><script src="/_next/static/chunks/framework-66d32731bdd20e83.js" defer="" crossorigin=""></script><script src="/_next/static/chunks/main-aa55ffd08992d156.js" defer="" crossorigin=""></script><script src="/_next/static/chunks/pages/_app-fc01fe4bbf4782bd.js" defer="" crossorigin=""></script><script src="/_next/static/chunks/pages/_error-ee5b5fb91d29d86f.js" defer="" crossorigin=""></script><script src="/_next/static/hOZ5KP5hbSt7VP82veGiT/_buildManifest.js" defer="" crossorigin=""></script><script src="/_next/static/hOZ5KP5hbSt7VP82veGiT/_ssgManifest.js" defer="" crossorigin=""></script></head><body><div id="__next"><script>!function(){try{var d=document.documentElement,c=d.classList;c.remove('light','dark');var e=localStorage.getItem('theme');if('system'===e||(!e&&true)){var t='(prefers-color-scheme: dark)',m=window.matchMedia(t);if(m.media!==t||m.matches){d.style.colorScheme = 'dark';c.add('dark')}else{d.style.colorScheme = 'light';c.add('light')}}else if(e){c.add(e|| '')}if(e==='light'||e==='dark')d.style.colorScheme=e}catch(e){}}()</script></div><script id="__NEXT_DATA__" type="application/json" crossorigin="">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"hOZ5KP5hbSt7VP82veGiT","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/_next/static/css/f4eeca13f57c12b5.css" as="style" crossorigin=""/><link rel="stylesheet" href="/_next/static/css/f4eeca13f57c12b5.css" crossorigin="" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" crossorigin="" nomodule="" src="/_next/static/chunks/polyfills-c67a75d1b6f99dc8.js"></script><script src="/_next/static/chunks/webpack-59c5c889f52620d6.js" defer="" crossorigin=""></script><script src="/_next/static/chunks/framework-66d32731bdd20e83.js" defer="" crossorigin=""></script><script src="/_next/static/chunks/main-aa55ffd08992d156.js" defer="" crossorigin=""></script><script src="/_next/static/chunks/pages/_app-b75415f3abaef78a.js" defer="" crossorigin=""></script><script src="/_next/static/chunks/pages/_error-ee5b5fb91d29d86f.js" defer="" crossorigin=""></script><script src="/_next/static/36BXZVOGgYj1qqQExiwkl/_buildManifest.js" defer="" crossorigin=""></script><script src="/_next/static/36BXZVOGgYj1qqQExiwkl/_ssgManifest.js" defer="" crossorigin=""></script></head><body><div id="__next"><script>!function(){try{var d=document.documentElement,c=d.classList;c.remove('light','dark');var e=localStorage.getItem('theme');if('system'===e||(!e&&true)){var t='(prefers-color-scheme: dark)',m=window.matchMedia(t);if(m.media!==t||m.matches){d.style.colorScheme = 'dark';c.add('dark')}else{d.style.colorScheme = 'light';c.add('light')}}else if(e){c.add(e|| '')}if(e==='light'||e==='dark')d.style.colorScheme=e}catch(e){}}()</script></div><script id="__NEXT_DATA__" type="application/json" crossorigin="">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"36BXZVOGgYj1qqQExiwkl","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"pageProps":{"tags":["react","next.js","렌더링","트러블슈팅","deepdive","dev tools","SSR","SSG","Algorithm","프로그래머스","PCCP","lv2","이분탐색","JavaScript","useState","hook","클로저","생명주기","Virtual DOM","백준","gold","dfs","lv3","bfs"],"currentTag":"이분탐색","posts":[{"slug":"posts/Algorithm/[PCCP 기출문제]퍼즐게임 챌린지","title":"[PCCP 기출문제] 퍼즐게임 챌린지","date":"2024-10-31T12:05:24.000Z","image":"index.jpg","summary":"프로그래머스 [PCCP 기출문제] level 2 퍼즐게임 챌린지 문제 풀이 입니다.","tags":["Algorithm","프로그래머스","PCCP","lv2","이분탐색"],"content":"# [PCCP 기출문제] 퍼즐게임 챌린지\r\n\r\n## 문제 요약\r\nhttps://school.programmers.co.kr/learn/courses/30/lessons/340212\r\n\r\n숙련도에 따라 퍼즐을 풀 때, \r\n- 각 퍼즐에서 난이도가 숙련도 보다 높다면 **난이도 - 숙련도 만큼 퍼즐이 틀리고, 틀린횟수 * (이전시간 + 현재시간)만큼의 시간이 걸린다.**\r\n- 각 퍼즐에서 난이도가 숙련도 보다 낮거나 같다면 **현재시간만** 투자하면 된다.\r\n\r\n이렇게 모든 퍼즐을 푼 시간의 합이 주어진 limit를 넘지 않도록 하는 숙련도(level)의 최솟값을 구하여야한다. \r\n\r\n(자세한 문제의 내용은 링크를 참고바랍니다.)\r\n\r\n## 문제 접근\r\n레벨의 최솟값을 구하여야 하기에, 처음에는 diffs 난이도 배열에서 최댓값부터 시작하여 1씩 줄어들도록 푸는 브루트포스를 생각했다.\r\n\r\n하지만, 제한사항이 1<=diffs[i]<=100000로 범위가 상당히 크고, diffs의 길이도 1 ≤ diffs의 길이 = times의 길이 = n ≤ 300,000로 제한사항이 주어졌기에\r\n\r\n브루트포스 기법은 무조건 시간초과가 날 것이므로 아닌 다른 방식을 생각해내야한다. \r\n\r\n결국 level의 값을 효율적이고 시간이 적게 들 수 있게 탐색해내야 하므로, O(nlogn)의 시간 복잡도를 가지는 **이분탐색으로 level의 최솟값을 구하면 된다.**\r\n\r\n## 풀이\r\n최대 난이도 이상의 값을 탐색하는 것은 의미가 없으므로, \r\n난이도의 최댓값을 구하여, max_diff로 놓은다음 이를 초기에 r로 설정한다.\r\nl은 난이도의 최솟값인 1로 두고,\r\n\r\n1~max_diff 범위 안에서 레벨의 이분탐색을 진행한다.\r\n\r\n현재 레벨을 변수 `level`로 둘 때,\r\n\r\n각 `level`에서 나올 수 있는 경우는 퍼즐을 푸는 시간의 합이 `limit`보다 **높을 때**와 **낮거나 같을 때**로 나눌 수 있다.\r\n- 시간의 합이 `limit`보다 높을 때: 현재 레벨이 낮기에 그런 것 이므로, 더 높은 레벨을 탐색하기 위해 \r\n`l = level+1` 로 둔다.\r\n\r\n- 시간의 합이 `limit` 보다 낮거나 같을 때: 현재 레벨이 충분히 높기에, 우리는 레벨의 최솟값을 찾아내야 하므로, \r\n`r = level-1`로 두고, 현재 레벨이 답이 될 수도 있기에 `answer = level` 도 추가해야 한다.\r\n\r\n이를 전체 코드로 구현하면 다음과 같다.\r\n\r\n## 전체 코드\r\n```js\r\n def solution(diffs, times, limit):\r\n max_diff = max(diffs)\r\n l = 1\r\n r = max_diff;\r\n answer = max_diff;\r\n while l<r:\r\n level = (l+r)//2;\r\n time = times[0]\r\n for i in range(1,len(diffs)):\r\n w_count = diffs[i]-level;\r\n if w_count > 0:\r\n time += w_count*(times[i-1] + times[i]) + times[i];\r\n else:\r\n time += times[i];\r\n if time>limit:\r\n l = level+1;\r\n else:\r\n r = level;\r\n answer = level;\r\n return answer;\r\n ```\r\n\r\n## 느낀 점\r\n한 동안 알고리즘 문제를 안풀었더니 뇌가 굳은게 아닌가 싶다. 그리고 문제 설명 자체가 길고 복잡하면 살짝 길을 잃는 습관이 있는데, 이번 문제에서도 이해해보면 그렇게 어렵지 않은 것 같음에도 불구하고 그런 습관이 나타난 것 같다. \r\n\r\n전에 백준에서 풀었던 이분탐색문제랑 거의 흡사했음에도 이분탐색을 빨리 떠올리지 못한게 아쉽다."},{"slug":"posts/Algorithm/[프로그래머스lv3]징검다리건너기","title":"[프로그래머스 level 3] 징검다리 건너기","date":"2024-07-08T18:33:24.000Z","image":"index.png","summary":"이분탐색을 활용한 프로그래머스 [level 3] 징검다리 건너기 문제 풀이 입니다.","tags":["Algorithm","프로그래머스","lv3","이분탐색"],"content":"# [level 3] 징검다리 건너기 - 64062\r\n\r\n## 문제 설명\r\n\r\n[](https://github.com/phnml1/CodingTest/blob/master/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/3/64062.%E2%80%85%EC%A7%95%EA%B2%80%EB%8B%A4%EB%A6%AC%E2%80%85%EA%B1%B4%EB%84%88%EA%B8%B0/README.md#%EB%AC%B8%EC%A0%9C-%EC%84%A4%EB%AA%85)\r\n\r\n**[본 문제는 정확성과 효율성 테스트 각각 점수가 있는 문제입니다.]**\r\n\r\n카카오 초등학교의 \"니니즈 친구들\"이 \"라이언\" 선생님과 함께 가을 소풍을 가는 중에 **징검다리**가 있는 개울을 만나서 건너편으로 건너려고 합니다. \"라이언\" 선생님은 \"니니즈 친구들\"이 무사히 징검다리를 건널 수 있도록 다음과 같이 규칙을 만들었습니다.\r\n\r\n- 징검다리는 일렬로 놓여 있고 각 징검다리의 디딤돌에는 모두 숫자가 적혀 있으며 디딤돌의 숫자는 한 번 밟을 때마다 1씩 줄어듭니다.\r\n- 디딤돌의 숫자가 0이 되면 더 이상 밟을 수 없으며 이때는 그 다음 디딤돌로 한번에 여러 칸을 건너 뛸 수 있습니다.\r\n- 단, 다음으로 밟을 수 있는 디딤돌이 여러 개인 경우 무조건 가장 가까운 디딤돌로만 건너뛸 수 있습니다.\r\n\r\n\"니니즈 친구들\"은 개울의 왼쪽에 있으며, 개울의 오른쪽 건너편에 도착해야 징검다리를 건넌 것으로 인정합니다. \r\n\"니니즈 친구들\"은 한 번에 한 명씩 징검다리를 건너야 하며, 한 친구가 징검다리를 모두 건넌 후에 그 다음 친구가 건너기 시작합니다.\r\n\r\n디딤돌에 적힌 숫자가 순서대로 담긴 배열 stones와 한 번에 건너뛸 수 있는 디딤돌의 최대 칸수 k가 매개변수로 주어질 때, 최대 몇 명까지 징검다리를 건널 수 있는지 return 하도록 solution 함수를 완성해주세요.\r\n\r\n#### [제한사항]\r\n\r\n[](https://github.com/phnml1/CodingTest/blob/master/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/3/64062.%E2%80%85%EC%A7%95%EA%B2%80%EB%8B%A4%EB%A6%AC%E2%80%85%EA%B1%B4%EB%84%88%EA%B8%B0/README.md#%EC%A0%9C%ED%95%9C%EC%82%AC%ED%95%AD)\r\n\r\n- 징검다리를 건너야 하는 니니즈 친구들의 수는 무제한 이라고 간주합니다.\r\n- stones 배열의 크기는 1 이상 200,000 이하입니다.\r\n- stones 배열 각 원소들의 값은 1 이상 200,000,000 이하인 자연수입니다.\r\n- k는 1 이상 stones의 길이 이하인 자연수입니다.\r\n\r\n----------\r\n\r\n#### [입출력 예]\r\n\r\n\r\n<table class=\"table\">\r\n <thead><tr>\r\n<th>stones</th>\r\n<th>k</th>\r\n<th>result</th>\r\n</tr>\r\n</thead>\r\n <tbody><tr>\r\n<td>[2, 4, 5, 3, 2, 1, 4, 2, 5, 1]</td>\r\n<td>3</td>\r\n<td>3</td>\r\n</tr>\r\n</tbody>\r\n </table>\r\n\r\n##### **입출력 예에 대한 설명**\r\n\r\n[](https://github.com/phnml1/CodingTest/blob/master/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/3/64062.%E2%80%85%EC%A7%95%EA%B2%80%EB%8B%A4%EB%A6%AC%E2%80%85%EA%B1%B4%EB%84%88%EA%B8%B0/README.md#%EC%9E%85%EC%B6%9C%EB%A0%A5-%EC%98%88%EC%97%90-%EB%8C%80%ED%95%9C-%EC%84%A4%EB%AA%85)\r\n\r\n----------\r\n\r\n**입출력 예 #1**\r\n\r\n첫 번째 친구는 다음과 같이 징검다리를 건널 수 있습니다. \r\n![1.png](1.png)\r\n\r\n첫 번째 친구가 징검다리를 건넌 후 디딤돌에 적힌 숫자는 아래 그림과 같습니다. \r\n두 번째 친구도 아래 그림과 같이 징검다리를 건널 수 있습니다. \r\n![2.png](2.png)\r\n\r\n두 번째 친구가 징검다리를 건넌 후 디딤돌에 적힌 숫자는 아래 그림과 같습니다. \r\n세 번째 친구도 아래 그림과 같이 징검다리를 건널 수 있습니다. \r\n![3.png](3.png)\r\n\r\n세 번째 친구가 징검다리를 건넌 후 디딤돌에 적힌 숫자는 아래 그림과 같습니다. \r\n네 번째 친구가 징검다리를 건너려면, 세 번째 디딤돌에서 일곱 번째 디딤돌로 네 칸을 건너뛰어야 합니다. 하지만 k = 3 이므로 건너뛸 수 없습니다. \r\n![4.png](4.png)\r\n\r\n따라서 최대 3명이 디딤돌을 모두 건널 수 있습니다.\r\n\r\n## 접근 방법\r\n브루트 포스로 1명씩 건너기에는, stones 배열의 크기가 최대 200,000이고, stones 배열의 각 원소들의 값 역시 최대 200,000,000이기 때문에, 시간 초과가 날 확률이 높다고 생각했고(사실 그렇게 쉬우면 lv3 일리가 없지), 아니나 다를까 시간초과가 났다. \r\n\r\n고민하다가 도저히 해결책이 안나와서 찾아보니 `이분탐색`을 사용하여 풀 수 있었다.\r\n\r\n- 건널 수 있는 인원의 최소는 1명, 최대는 max(stones)명이다. 모든 돌들의 합이 같거나, 다르다 하더라도 건널수 없는 곳이 k이하면 건널 수 있기 때문이다. \r\n- 따라서 start = 1 end = max(stones)로 이분탐색을 시작할 수 있다.\r\n\r\nmid 값만큼의 사람이 건널 수 있는지 확인하기 위한 check함수는 다음과 같다.\r\n```python\r\ndef check(stones, mid,k):\r\n cnt = 0;\r\n for stone in stones:\r\n\t # 밟을 수 없으므로 건너뛰어야하는 횟수를 늘린다.\r\n if (stone - mid) <= 0:\r\n cnt += 1;\r\n # 밟을 수 있으므로 최대 건너뛰는 횟수를 초기화시킨다.\r\n else:\r\n cnt = 0;\r\n # 건너뛰는 횟수가 k보다 크거나 같으면 안되므로 False 리턴 \r\n if cnt>=k:\r\n return False;\r\n return True;\r\n```\r\n건널 수 있다면 mid보다 큰 범위에서 값을 찾아야하므로 start를 mid+1로 갱신하고, 반대라면, mid보다 작은 범위에서 값을 찾아야하므로 end를 mid-1로 갱신한다.\r\n \r\ncheck 시간 복잡도는 O(N)이고 이분탐색을 했을 때 O(logN)의 시간복잡도가 나오므로, 총 O(NlogN)의 시간 복잡도가 나오므로, 시간초과가 나지 않는다.\r\n\r\n전체 코드는 다음과 같다.\r\n```python\r\ndef check(stones, mid,k):\r\n cnt = 0;\r\n for stone in stones:\r\n if (stone - mid) <= 0:\r\n cnt += 1;\r\n else:\r\n cnt = 0;\r\n if cnt>=k:\r\n return False;\r\n return True;\r\n\r\ndef solution(stones, k):\r\n start,end = 1,max(stones);\r\n answer = 0;\r\n while start<=end:\r\n mid = (start + end) // 2;\r\n if check(stones, mid,k):\r\n start = mid+1;\r\n else:\r\n answer = mid;\r\n end = mid-1; \r\n return answer;\r\n```\r\n\r\n## 느낀 점\r\n이분탐색 문제를 많이는 아니더라도 어느정도는 풀어봤다고 생각했는데, 이 문제에서 이분탐색으로 푸는 아이디어를 떠올리지 못해서 아쉽다. \r\n\r\n또한 처음에 위에 코드의 6번째줄에서 else문을 쓰지않고, 이러한 코드로 제출하여서 시간초과가 났다.\r\n```python\r\nif (stone - mid) <= 0:\r\n\tcnt += 1;\r\nif (stone - mid)>0:\r\n\tcnt = 0;\r\n```\r\nㅎㅎ.. 사실 위와 같은 경우에서 if else문을 쓰는 것이 기본인데, 그래도 시간초과가 날 수 있는 직접적인 원인까지는 되지 않을 거라고 안일하게 생각해서 코드를 짠 게 화근이었다. 기본을 지키자!"}]},"__N_SSG":true}
Loading

0 comments on commit d026020

Please sign in to comment.