ChoiCube84's Blog A Blog made by ChoiCube84 https://choicube84.github.io/ Tue, 13 Jan 2026 15:54:39 +0900 Tue, 13 Jan 2026 15:54:39 +0900 Jekyll v3.10.0 Self-Attention with Relative Position Representations 논문 리뷰 <h1 id="self-attention-with-relative-position-representations">Self-Attention with Relative Position Representations</h1> <p>오늘 리뷰해 볼 논문은 Self-Attention with Relative Position Representations <sup><a href="#footnote_1">1</a></sup> 이다. 이 논문을 읽게 된 이유는, 원래 RoPE 논문을 읽고 있었는데 기습 출현했기 때문이다… 그렇지만 아이디어의 흐름을 이해하는 데 중요한 논문 중 하나인 것 같아 읽어보고 리뷰까지 진행하기로 결정했다.</p> <h2 id="세-줄-요약">세 줄 요약</h2> <ul> <li> <p><strong>위치 정보 인코딩을</strong></p> </li> <li> <p><strong>토큰 위치 차이 (거리) 기반으로</strong></p> </li> <li> <p><strong>Value 와 Key 에 더해준다.</strong></p> </li> </ul> <h2 id="논문을-읽으며-들었던-생각의-흐름">논문을 읽으며 들었던 생각의 흐름</h2> <h3 id="논문에-익숙하지-않은-나">논문에 익숙하지 않은 나</h3> <p>논문을 처음 봤을 때 든 생각은, 뭐가 이렇게 글자가 많은가 하는 생각이었다… 이 글은 최초로 논문을 리뷰하는 글인데, 아직 내가 논문을 별로 읽어 본 경험이 없어서 이런 생각이 들었을지도 모르겠다. 어쨌든 꾸역꾸역 영어들을 읽어나가다 보니, 2장에 가서야 무슨 소리를 하고 싶은지 본격적으로 이해할 수 있었다.</p> <h3 id="늘-보던-그-식">늘 보던 그 식</h3> <p>2.2 에서 설명하는 내용은 그냥 지겹게 보던 self-attention 수식을 다시 써놨을 뿐이었다. 한 가지 주목할 점이 있다면, $v_j$, $q_i$, 혹은 $k_j$ 같은 문자로 value, query, key 를 나타내는 대신, 꼬박꼬박 입력 $x_i$ 혹은 $x_j$ 에다가 행렬 $W^V$ 등을 곱한 표현을 이용했다는 것이다. 왜 그렇게 했을까? 그건 모르겠다. 내 뇌피셜로는, 아마 self-attention 연산이 일어나는 과정을 좀 더 명시적으로 보여주고 싶었음이 아닐까 싶었다.</p> <h3 id="본론">본론</h3> <p>본 게임은 3장부터 시작이었다. 드디어 이 논문에서 제안하고자 하는 바를 표현하기 시작한 것이다. 논문 기준으로 (3) 식을 보면, value 값인 $x_j W^V$ 에 $a_{ij}^V$ 를 더해주는 것을 볼 수 있었다. (4) 식에서는 key 값인 $x_j W^K$ 에 $a_{ij}^K$ 를 더해주는 것을 볼 수 있었다. 처음에는 세상 온갖 첨자가 튀어나와 많이 당황스러웠는데, 생각보다 별건 아니었다. 나중에 나온 식들과 함께 보면 간단한 내용이었다.</p> <p>결국 3장을 통해 저자들을 하고 싶었던 건, 토큰 간의 위치 차이 (거리) 를 기반으로 위치 인코딩을 심어주는 것이었고, 이를 위해 기존의 self-attention 식을 조금 수정했을 뿐인 것이었다. 각 $a$ 의 역할은 value / key 에 더해줄 인코딩 값을 담는 것이고, 아래 첨자에 $ij$ 라고 써있는 건 $i$ 번째 토큰과 $j$ 번째 토큰 사이의 attention 연산 과정에서 더해주는 값이라는 의미인거고, 위 첨자로 $V$, $K$ 라고 써있는 건 그냥 ‘V’alue 에 더하는지, ‘K’ey 에 더하는 지 차이를 나타낼 뿐이었다.</p> <p>3.2 에서 $a$ 들의 정체가 밝혀지는데, 처음에 식을 보고 대체 뭔소린가 한참을 고민했었다. 그러나 별 어려운 내용은 역시 아니었다. $a_{ij}^K = w_{\text{clip}(j-i, k)}^K$ 라고 써있는 것은, 위 첨자가 $K$ 니까 key 쪽에 더해주는거고, $ij$ 파트는 $j - i$ 형태로 바뀌어, 그 자체의 위치 보다는 두 위치의 차이가 반영되는데, 여기서 $\text{clip}$ 함수를 먹여서 두 개 차이가 너무 막 나가는 걸 막아준 것이다. $\text{clip}$ 함수가 무엇인가 하니, 양수 뱡향이던 음수 방향이던 절댓값이 주어진 어떤 $k$ 를 벗어나면 강제로 그 절댓값을 $k$ 로 제한하는 것이었다. 예를 들어, $k = 10$ 이라고 하면, 두 토큰 위치 차이가 $6$ 이면 $\text{clip}(6, 10) = 6$ 인 것이고, 두 토큰 위치 차이가 $-20$ 이면 $\text{clip}(-20, 10) = -10$ 인 것이다.</p> <p>그래서 그 더해주는 값들의 종류는 key 와 value 쪽 각각 $w_{-k}$ 부터 $w_k$ 까지 총 $2k+1$ 종류의 값들이 필요하고, 논문에서는 이것들을 학습시키면 된다고 한다. 사실 이 시점에서 논문에서 하고 싶은 말은 거의 다 끝났다.</p> <p>뒷 부분은 효율적인 구현을 위해 식을 다르게 전개해서 연산을 진행하는 내용과, 실험 결과를 담고 있는데, 솔직히 논문의 아이디어와 방법론을 이해하는데 별로 도움이 되지는 않으니 설명을 스킵하겠다.</p> <h3 id="주요-의문점">주요 의문점</h3> <p>논문을 다 읽고 나니 한 가지 궁금한 부분이 생겼다. 참고로 이 의문에 대한 명쾌한 답은 찾지 못했다.</p> <blockquote> <p>어째서 위치 인코딩을 key 와 value 쪽에만 심어두고 query 는 가만히 내버려두었을까?</p> </blockquote> <p>내 뇌피셜에 따르면, 연구진들은 딱히 query 만 차별하려고 했던 것은 아닐 것 같다. 원래대로라면 query, key, value 에 전부 넣으려고 했겠지만, ‘어짜피 query 와 key 는 곱해지는데, 둘 중 한 곳에만 위치 정보를 넣는 것으로 충분하지 않나?’ 라는 식의 아이디어가 아니었을까 싶다.</p> <p>그렇다면 query 와 key 둘 중 하나를 고르는데 어째서 그것이 key 여야 했는가에 대한 의문은, 나름대로 2가지 가설이 있다.</p> <ol> <li> <p>첫 번째로는 key 쪽이 value 와 같은 $x$ 에 대한 인덱스를 가지고 있기 때문이고,</p> </li> <li> <p>두 번째로는 query 와 key 에 대한 의미론적인 느낌 상, query 는 광장에다가 대고 ‘누구 나랑 관련있는 사람 없습니까?’ 하고 소리지르는 느낌이고, key 는 ‘나 여깄소!’ 하고 대답하는 느낌이니까, 대답하는 쪽이 상대적 위치 정보를 들고 있는게 더 자연스럽다고 생각했을 것이기 때문이다.</p> </li> </ol> <p>당연히 둘 다 내 뇌피셜이고, 논문에서는 관련 설명을 발견하지 못했다. 이 의문은 다른 논문들을 읽다보면 저절로 풀리게 될까? 그건 시간만이 말해줄 것이다.</p> <h2 id="마무리">마무리</h2> <p>최초로 ‘논문 리뷰’ 라는 걸 해봤다. 사실 논문 리뷰라고는 해도, 읽으면서 들었던 생각이나 의문점을 정리해보는 거라 일반적인 느낌의 논문 리뷰와는 거리가 있지만, 어짜피 내용을 친절하게 상세하게 잘 풀어둔 글들은 세상에 많기 때문에, 내가 그런 중복되는 중노동을 해봐야 <del>아무도 안 읽기 때문에</del> 의미가 없다고 생각했다.</p> <p>이런 식으로 다른 논문들도 읽어보고 가능하면 글로 정리해볼 계획이다. 논문 리뷰가 고작 이 논문 하나로 끝나지 않았으면 좋겠다.</p> <p>오늘은 여기까지!</p> <hr /> <p><a name="footnote_1">1</a>: <a href="https://arxiv.org/abs/1803.02155">https://arxiv.org/abs/1803.02155</a></p> Tue, 13 Jan 2026 23:59:00 +0900 https://choicube84.github.io/study/2026/01/13/shaw_et_al_2018.html https://choicube84.github.io/study/2026/01/13/shaw_et_al_2018.html paper_review Study 군전역 <h1 id="군전역">군전역</h1> <p>2025년 8월 12일 부로 나는 전역하게 되었다. 이번 글에서는 군생활 동안 있었던 일과 앞으로의 계획에 대해서 이것저것 이야기 해보려고 한다.</p> <h2 id="군생활-정리">군생활 정리</h2> <blockquote> <p>초-간단 요약: <strong>좋은 친구를 얻고, 발목을 잃었다.</strong></p> </blockquote> <h3 id="전반적인-군생활-흐름">전반적인 군생활 흐름</h3> <p>나는 운전병으로 입대하게 되며, 신병교육대대에서 5주간 기초군사훈련을 받은 뒤, 수송교육연대에서 운전병이 되기 위한 후반기 교육을 받게 되었다. 이후 통신단의 통신대대의 통신중대로 자대배치를 받게되었다.</p> <p>해당 부대에서 중형차량 운전병으로서 복무하였으며, 주 업무는 세차였다… 운전대는 거의 잡아보지 못했다. 부대 특성 상 장거리 배차가 많지 않으며, 개인 차가 있긴 하지만 신병 운전병이 배차를 나갈 수 있게 되기까지 나름의 절차와 시간이 필요한데, 이 과정에서 운이 나쁘면 얼마든지 밀릴 수 있다. 내가 그런 케이스였다.</p> <p>일과 시간 동안은 주로 부대 내의 수송부로 이동하여 수송부 작업을 했고, 개인정비 시간에는 주로 생활관에서 휴식을 취하거나 사이버지식정보방 (이하 사지방) 에서 공부(주로 코딩) 을 했다.</p> <p>부대 특성 상 파견을 종종 간 적이 있다. 다만 앞서 이야기했던 것처럼 타이밍이 대부분 좋지 않아 운전을 할 기회가 거의 없다시피 했다. 오랜 기다림 끝에 배차를 나갈 기회들이 생겼지만, 후술할 발목 관련 문제로 인해 부대 내에서의 운전의 가능성의 문은 영영 닫히게 되었다.</p> <p>2025년 3월 첫 휴가 (24년도 8월에 나갔던 신병위로’외박’ 제외) 때 밤마다 ‘왼쪽’ 발목이 시큰거리는 경험을 했다. 자고 일어나면 괜찮아지길래 휴가동안에는 내버려뒀지만, 부대에서도 이 증상이 지속되길래 병원에가서 진료를 봤고, ‘오른쪽’ 발목에 이단성 골연골염이 있음이 확인되었다. 양쪽을 모두 찍어보자고 한 의사의 판단이 빛났던 순간이었다.</p> <p>결국 4월 후반부에 수술을 받게 되었다. 골수를 연골이 파인 부분에 심어 자라도록 하는 방식의 재생술이었다. 완전히 나아 다시 뛸 수 있게 되기까지는 1년이 걸린다고 했다. 따라서 글을 쓰고 있는 지금, 8월에도, 목발이나 보조 기구 없이 보행은 가능하지만 발목이 여전히 아프며, 뛸 수도 없다. 애초에 실수로라도 뛰려고 하면 갑자기 발목이 아프며 제동이 걸리는 느낌이 든다.</p> <p>발목 수술 이후 몇 달간 입원한 채 지냈으며, 퇴원 이후로는 부대에 복귀했는데 수송부에 내려가 일을 할 수 없어 행정반에 납치당했다. 그 상태로 말년을 보낸 뒤 최종적으로 2025년 8월 12일에 전역하게 되었다.</p> <h3 id="일과-외-활동들">일과 외 활동들</h3> <p>앞서 이야기한 것 처럼 운전 대신 잡일이나 세차가 대부분이었던 일과에 대해서는 솔직히 자세하게 설명하려고 해도 별로 할 것도 없고, 별로 하고 싶지도 않으니 일과 외 활동들에 대해서 정리해보려고 한다.</p> <p>위에서도 이야기 한 것 처럼 일과 외 시간에는 놀거나 공부를 했다. 개인정비시간에 공부를 해보는 것을 몇 번 시도해봤는데, 잘 되지도 않아서 그냥 깔끔하게 놀아버리고 연등 시간을 활용해서 공부를 했다.</p> <p>초기에는 백준 문제를 푸는 것과 해석학 문제들을 푸는 것을 위주로 해왔고, 24년도 말기부터는 친한 동기와 함께 RISC-V CPU를 Verilog 를 이용하여 구현하는 프로젝트를 진행했다. 이 동기가 위에서 이야기한 나의 친한 친구이다.</p> <p>이 친구는 3월 군번 친구로 9월에 전역할 예정이다. 입대는 나보다 한 달 늦게했지만 야수교를 다녀오는 과정에서 나랑 자대배치는 같은 날 같은 부대 같은 중대로 받았다.</p> <p>부대에 오고나서 초기에는 신병보호기간이라고 해서 거의 아무것도 시키지 않고 생활관에서 대기하다가 지휘관 면담 등을 하는 기간이 있다. 이 기간동안 급속도로 친해졌는데, 둘 모두 하드웨어냐 소프트웨어냐로 갈리기는 해도 컴퓨터공학이 전공분야로 일치하는 등 관심분야가 일치하는 것이 많았던 것이다.</p> <p>그 친구와는 부대에서 많은 시간과 많은 추억들을 쌓았고, 관련해서 글들을 따로 쓸 수 있을 정도이지만 이 정도로만 이야기하도록 하겠다.</p> <h2 id="군생활-목표는-어찌되었는가">군생활 목표는 어찌되었는가</h2> <p>목표가 크게 3가지 있었다. 어쩌면 4가지라고 해야하려나?</p> <ol> <li> <p>다치지 않고 무사히 전역하기</p> </li> <li> <p>해석학 교재 (Principles of Mathematical Analysis) 모든 문제 다 풀고 정리하기</p> </li> <li> <p>solved.ac 클래스 6, 7 문제 모두 해결하기</p> </li> <li> <p>현대대수학 예습하기</p> </li> </ol> <p>결론부터 말하면 전부 실패했다… 하나씩 따져보자.</p> <h3 id="다치지-않고-무사히-전역하기">다치지 않고 무사히 전역하기</h3> <p>일단 일상생활이 가능한 형태로 살아 돌아오기는 했지만, 다치지 않고 라는 조건에서 실패하고 말았다.</p> <p>발목 수술을 받게 되며 이동이나 활동에 상당한 지장이 생겨버렸고, 그것이 군대 안에서 해결된 것이 아니라 복학을 하고 나고서도 한동안 안고 가야하는 페널티가 되고 말았다…</p> <p>뛰기까지는 앞으로 8개월 정도는 더 있어야 하는 것 같은데, 앞으로 어찌될지 걱정스럽다.</p> <h3 id="해석학-교재-모든-문제-다-풀고-정리하기">해석학 교재 모든 문제 다 풀고 정리하기</h3> <p>여기서 모든 문제라고 호기롭게 적어두기는 했지만, Chapter 10 의 경우는 수업에서 다루지 않았던 내용이기도 하고, Chapter 11 의 르벡 적분의 경우는 다른 교재를 이용해 다뤘으므로, 제외하여 실질적으로 9개의 단원을 풀 것으로 목표를 조정해 둔 상태였다.</p> <p>조정을 하면 뭐하는가 그마저도 못하는데. 일단 군생활 동안에는 Chapter 3 까지 문제를 전부 풀어내는 것은 성공했다. 풀이를 추가적으로 검증하고 정리하고 보완하는 작업도 진행해야겠지만 말이다.</p> <p>목표 달성 실패와는 별개로, 스스로 칭찬해주고 싶은 부분은 있다. 3단원이면 9단원 중 1/3 에 불과하긴 해도, 어느정도 유의미한 성과였다고 생각한다. 가장 골칫거리였던 2단원을 모조리 뚫어내고, 그걸 끝내고 장렬히 산화한 것이 아니라 3단원까지 밀어냈기 때문이다! 그리고 3단원을 끝내고 장렬히 산화한 게 아니라, 4단원도 밀고 있다가 타이머가 울려버린 것이기 때문에, 목표의 성패 여부와는 상관없이 크게 성장하는데에는 성공했다고 스스로를 칭찬해주고 싶다.</p> <h3 id="solvedac-클래스-6-7-문제-모두-해결하기">solved.ac 클래스 6, 7 문제 모두 해결하기</h3> <p>마찬가지로 실패했다. 클래스 6 달성은 어찌저찌 성공했으나 7은 커녕 6 마스터도 달성하지 못했다.</p> <p>이건 내가 중간에 백준을 하다 권태감이 심하게 들어 그만둔 것도 큰 부분을 차지한다. 물론 그렇다고 해서 그것이 계획을 저버려도 되는 이유가 되지는 않겠지만 말이다.</p> <p>뭐, 내년도 PPC를 나갈 계획이 있기도 하고, 권태감도 사라진지 꽤 시간이 흘렀으니 슬슬 다시 밀려하면 밀리지 않을까 싶다.</p> <h3 id="현대대수학-예습하기">현대대수학 예습하기</h3> <p>아깝게 실패했다. 조금만 더 부지런했다면 성공했을 것이다.</p> <p>처음에는 교재의 문제들을 풀어가면서 직접 공부하는 방식을 생각해봤지만 잘 될리가 없었다. 한 가지 다행인 건, 어떤 유능한 수학교육과 출신 버튜버 분<sup><a href="#footnote_1">1</a></sup>이 좋은 강의 영상을 올려주셔서 거의 다 봤다!</p> <p>하지만 ‘거의’ 다 본 것은 다 본것이 아니다. 안타깝게도 실로우 정리 근처에서 내가 머리가 터져 쉬고 있었는데, 쉬다가 전역을 맞이하고 말았다. 따라서 결론은 실패…</p> <h2 id="앞으로의-계획">앞으로의 계획</h2> <p>사실 계획이랄게 별로 없다. 화요일 부터 시작되는 가족 여행을 다녀온 뒤로는 이제 포항으로 돌아갈 준비를 하고, 포항에 돌아가서 이 과목 저 과목 과제로 두들겨 맞으며 버텨내는 삶을 다시 살아야 한다.</p> <p>일단 그 전에, 아주 짧게 남은 시간 동안 현대대수 강의는 완강하고 가려고 한다. 물론 그 버튜버 분의 강의가 끝난 것은 아니다. 하지만 현재 유튜브 업로드 분 기준으로 봤을 때는 현대대수학 1 범위까지는 전부 커버되기 때문에 괜찮다. 그런 의미로 완강인 것이다. 해석학이니 solved.ac 이니 하는 것들은 우선 보류해두겠다.</p> <h2 id="마무리">마무리</h2> <p>군생활에 대해서 하고 싶은 말이 상당히 많긴 하지만, 여기서 굳이 그걸 열심히 적고 있는 건 별 의미가 없을 것 같다. 지금은 달려 나아갈 때이다.</p> <p>사람들은 흔히 주변의 남과 자신을 비교하면 불행해지기 마련이라고 하지만, 스스로의 위치나 상태를 확인하기에 비교만큼 좋은 도구가 없다고 생각한다. 그런 관점에서 봤을 떄, 벌써 3학년이 된 내가 이뤘다고 할 수 있는 건 이 정도 밖에 없다.</p> <ol> <li> <p>POSTECH 입학</p> </li> <li> <p>육군 병장 만기 전역</p> </li> <li> <p>RISC-V CPU 구현 프로젝트<sup><a href="#footnote_2">2</a></sup>에 기여</p> </li> </ol> <p>물론 이것들이 별거 아니라는 의미가 아니다. 주관적으로 봐도, 객관적으로 봐도, 이 3가지 업적 모두 무시하지 못할 상당한 업적들이라고 생각한다. 그러나, 이 3가지만 가지고서는 내가 이루고자 하는 목표를 달성하는 데는 택도 없다.</p> <p>POSTECH 은 명실상부 대한민국의 최고 수준의 공과대학교이지만, 전 세계에는 그런 ‘국가 최고 수준의 공과대학’ 은 무수히 많으며, 각 대학 안에 무수히 많은 인재들이 있다. 1번 업적은 앞으로 내가 하고 싶은 일을 하는데 있어 잠재력이 있다는 것 까지만 증명해주는 것이다.</p> <p>육군 병장 만기 전역이라는 타이틀은 대한민국에서 성인 남성으로 살아가는데 있어 신체적/정신적으로 이상이 없는 사람임을 간단명료하게 증명하는 깔끔한 타이틀이다. 그러나 내가 원하는 건 전 세계적인 무대에서 활동하는 것이다. 국내에서만 활동하는 건 역으로 우리나라에게 내가 줄 수 있는 도움도 제한하게 될 것이다.</p> <p>RISC-V CPU 구현 프로젝트는 내 동기와 함께한 프로젝트이다. 컴퓨터 구조 수업에서 사용할 전공책을 미리 구입해서 열심히 싱글사이클 프로세서까지는 구현했지만, 솔직히 파이프라이닝부터 시작해서 이걸 FPGA 에 올려 검증하는 건 전부 그 동기가 했다고 봐도 무방하다. 그리고 싱글사이클 프로세서 제작도 GPT의 도움을 상당히 많이 받아왔다. 이 프로젝트에 참여했던 경력이 내가 컴퓨터구조 수업을 듣고 이해하며 과제를 수행하는데 상당한 도움이 되리라는 것은 의심할 여지가 없지만, 프로젝트가 창출해낸 학술적 가치를 내가 얻어낸 것이라고 주장할 정도로 뻔뻔한 사람이 될 수는 없었다. 이러한 성과들이 나름 대단하고 중요한 건 맞지만, 이것만으로는 부족함을 느끼고 있다.</p> <p>부대에서도 계속 봐왔지만, 주변의 친구들은 모두들 열심히 달려나가고 있었다. 그냥 달려나가는 정도가 아니라, 한참 앞으로 치고 나가있는 상태였다. 전래동화로 비유하면 성실하고 꾸준한 토끼들이 게으르고 잠 많은 거북이가 나무에서 자고 있을 동안 폐가 찢어질 정도로 열심히 달려나갔던 것이다. 실제로 내 친구들 대부분 나보다 훨씬 좋은 학점을 유지하는 상태로 (이건 다들 거의 기본으로 깔고 들어간다…) 취업을 해본 경험이 있다거나, 학교에서 추가적인 장학금을 받았다거나, 랩실에 들어가서 열심히 연구를 진행한 경험이 있다거나, 포카전 AI 선수단을 훌륭하게 이끌어 학교에 영예를 안겼다거나, 특정 분야를 깊게 파서 이미 논문을 작성한 경험이 있다거나, <del>여자친구가 있다거나</del> 하는 내가 갖지 못한 그런 무시무시한 경력들을 가지고 있었다.</p> <p>따라서 이번 3학년의 컨셉은 ‘증명’ 이다. 나에게도 저런 어마무시한 업적을 이뤄낼 힘이 있다는 것을 증명하고자 한다. POSTECH 이라는 방패는 곧 사용기간이 만료된다. 내가 내 주장이나 생각을 당당하게 말해도 바보 취급받지 않고 존중받을 수 있었던 것은 내가 이제까지 해온 것이 있었기 때문이다. 그것이 사라지면 무엇도 나를 지켜주지 않는다. 이제는 새로운 방패를 만들 때가 된 것이다.</p> <p>구체적으로 어떻게 증명할 것인가 하면, 크게 3가지로 나눌 수 있겠다.</p> <ol> <li>학점 관리</li> <li>자기 관리</li> <li>AI 프로젝트 진행</li> </ol> <p>학점 관리의 경우는 말 그대로 학점을 관리하는 것이다. 이제까지 나는 매주 나오는 과제를 하는데 급급하여 제대로 공부를 하지도 못했고, 공부를 한다해도 ‘성적을 잘 받기 위한’ 공부를 해오지 않았다. 이런 공부가 진정한 의미가 있는 공부인지 아닌지에 대한 논의는 지금의 나에겐 의미가 없다. 왜냐하면 지금 중요한 것은 ‘증명’ 이기 때문이다. 따라서 학점 관리를 위해 전반적인 생활 습관 개선부터 시작해서 공부하는 방식, 습관, 전략 등을 다양하게 시도해보고 수정해볼 계획이다.</p> <p>자기 관리의 경우도 말 그대로 자기를 관리하는 것이다. 이건 학점 관리와도 어느 정도 연결되는 구석이 있다. 내가 2년간 POSTECH 을 다니면서 학점을 제대로 관리하지 못한데에는 여러 원인이 있지만, 가장 큰 원인 중 하나는 불규칙한 생활 패턴이라고 생각한다. 생활 패턴이라는 것은, 식사/수면 등 생활에 있어 기본적으로 잘 갖춰져야 할 여건들에 대한 패턴을 의미하는 것이다. 이런 부분들을 우선적으로 고쳐나가는 것부터 자기 관리를 이뤄낼 계획이다. 물론, 학점과 관련된 자기 관리만을 할 계획은 아니다. 나의 용모를 가꾼다거나, 패션을 완벽히는 몰라도 공부하는 시늉이라도 한다거나, 좀 더 인간 관계를 잘 이끌어 나가기 위해 스스로의 나쁜 습관을 고쳐본다거나 하는 노력들을 해볼 것이다.</p> <p>AI 프로젝트를 진행하는 건, 며칠 전에 만났던 고등학교 친구와 계획한 프로젝트이다. 그 친구도 나도 모두 AI, 특히 ChatGPT 같은 LLM 에 관심이 있는데, 이러한 거대 언어 모델을 직접 구축해보고 성능을 개선하기 위한 연구들을 진행해볼 계획이다. 군대에서 다른 친구와 진행했던 CPU 프로젝트의 성공으로 어느정도 자신감과 아이디어를 얻어 시작할 수 있게 되었다.</p> <p>평소쓰는 블로그 글의 마무리치고는 꽤 긴 편이다. 마지막 문장으로 군대에서 만난 친구의 말을 인용하며 글을 마무리하겠다.</p> <blockquote> <p>그렇기에 내가 갈망하는 미래가 올 것임을 믿고 나아가는 수 밖에 없다.</p> </blockquote> <hr /> <p><a name="footnote_1">1</a>: <a href="https://www.youtube.com/@math%EC%97%B0%EB%96%A0">https://www.youtube.com/@math%EC%97%B0%EB%96%A0</a></p> <p><a name="footnote_2">2</a>: <a href="https://github.com/RISC-KC/basic_rv32s">https://github.com/RISC-KC/basic_rv32s</a></p> Mon, 18 Aug 2025 10:36:00 +0900 https://choicube84.github.io/life/2025/08/18/escaping_from_the_military.html https://choicube84.github.io/life/2025/08/18/escaping_from_the_military.html military Life 백준 2618번 <h1 id="백준-2618번">백준 2618번</h1> <p>오늘 풀어본 문제는 백준의 2618번 문제<sup><a href="#footnote_1">1</a></sup>이다. 문제 풀이에 사용한 언어는 C++ 이다.</p> <h2 id="solvedac-기준-class">solved.ac 기준 CLASS</h2> <p><img src="https://static.solved.ac/class/c6.svg" width="50%" height="50%" alt="CLASS 6" /></p> <h2 id="문제-정보">문제 정보</h2> <p>이 문제의 내용과 조건은 다음과 같다.</p> <h3 id="문제">문제</h3> <p>어떤 도시의 중심가는 $N$ 개의 동서방향 도로와 $N$ 개의 남북방향 도로로 구성되어 있다.</p> <p>모든 도로에는 도로 번호가 있으며 남북방향 도로는 왼쪽부터 $1$ 에서 시작하여 $N$ 까지 번호가 할당되어 있고 동서방향 도로는 위부터 $1$ 에서 시작하여 $N$ 까지 번호가 할당되어 있다. 또한 동서방향 도로 사이의 거리와 남 북방향 도로 사이의 거리는 모두 $1$ 이다. 동서방향 도로와 남북방향 도로가 교차하는 교차로의 위치는 두 도로의 번호의 쌍인 $(\text{동서방향 도로 번호}, \text{남북방향 도로 번호})$ 로 나타낸다. $N$ 이 $6$ 인 경우의 예를 들면 다음과 같다.</p> <p><img src="https://upload.acmicpc.net/6b5a6518-1801-46c9-9b17-49e8abb3bc88/" width="50%" height="50%" alt="figure 1" /></p> <p>이 도시에는 두 대의 경찰차가 있으며 두 차를 경찰차1과 경찰차2로 부른다. 처음에는 항상 경찰차1은 $(1, 1)$ 의 위치에 있고 경찰차2는 $(N, N)$ 의 위치에 있다. 경찰 본부에서는 처리할 사건이 있으면 그 사건이 발생된 위치를 두 대의 경찰차 중 하나에 알려 주고, 연락 받은 경찰차는 그 위치로 가장 빠른 길을 통해 이동하여 사건을 처리한다. (하나의 사건은 한 대의 경찰차가 처리한다.) 그리고 사건을 처리 한 경찰차는 경찰 본부로부터 다음 연락이 올 때까지 처리한 사건이 발생한 위치에서 기다린다. 경찰 본부에서는 사건이 발생한 순서대로 두 대의 경찰차에 맡기려고 한다. 처리해야 될 사건들은 항상 교차로에서 발생하며 경찰 본부에서는 이러한 사건들을 나누어 두 대의 경찰차에 맡기되, 두 대의 경찰차들이 이동하는 거리의 합을 최소화 하도록 사건을 맡기려고 한다.</p> <p>예를 들어 앞의 그림처럼 $N=6$ 인 경우, 처리해야 하는 사건들이 $3$ 개 있고 그 사건들이 발생된 위치 를 순서대로 $(3, 5)$, $(5, 5)$, $(2, 3)$ 이라고 하자. $(3, 5)$ 의 사건을 경찰차2에 맡기고 $(5, 5)$ 의 사건도 경찰차2에 맡기며, $(2, 3)$ 의 사건을 경찰차1에 맡기면 두 차가 이동한 거리의 합은 $4 + 2 + 3 = 9$ 가 되 고, 더 이상 줄일 수는 없다.</p> <p>처리해야 할 사건들이 순서대로 주어질 때, 두 대의 경찰차가 이동하는 거리의 합을 최소화 하도록 사건들을 맡기는 프로그램을 작성하시오.</p> <h3 id="입력">입력</h3> <p>첫째 줄에는 동서방향 도로의 개수를 나타내는 정수 $N$ $(5 \le N \le 1,000)$ 이 주어진다. 둘째 줄에는 처리해야 하는 사건의 개수를 나타내는 정수 $W$ $(1 \le W \le 1,000)$ 가 주어진다. 셋째 줄부터 $(W+2)$ 번째 줄까지 사건이 발생된 위치가 한 줄에 하나씩 주어진다. 경찰차들은 이 사건들을 주어진 순서대로 처리해야 한다. 각 위치는 동서방향 도로 번호를 나타내는 정수와 남북방향 도로 번호를 나타내는 정수로 주어지며 두 정수 사이에는 빈칸이 하나 있다. 두 사건이 발생한 위치가 같을 수 있다.</p> <h3 id="출력">출력</h3> <p>첫째 줄에 두 경찰차가 이동한 총 거리를 출력한다. 둘째 줄부터 시작하여 $(i+1)$ 번째 줄에 $i$ $(1 \le i \le W)$ 번째 사건이 맡겨진 경찰차 번호 $1$ 또는 $2$ 를 출력한다.</p> <h2 id="풀이과정">풀이과정</h2> <h3 id="1번째-시도">1번째 시도</h3> <p>문제를 해결하기 위해 DP 를 이용했다.</p> <p>2차원 배열을 이용하여, 각 인덱스가 경찰차1과 경찰차2가 마지막으로 맡았던 사건의 번호가 되도록 하였을 때, 그렇게 되기 위해 필요한 최소 이동거리를 저장하게 하는 방식이었다.</p> <p>코드는 다음과 같이 작성하였다.</p> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;bits/extc++.h&gt;</span><span class="cp"> </span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">__gnu_pbds</span><span class="p">;</span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">using</span> <span class="n">ll</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">long</span><span class="p">;</span> <span class="k">using</span> <span class="n">ull</span> <span class="o">=</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="kt">long</span><span class="p">;</span> <span class="k">using</span> <span class="n">ld</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">double</span><span class="p">;</span> <span class="k">using</span> <span class="n">pll</span> <span class="o">=</span> <span class="n">pair</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;</span><span class="p">;</span> <span class="n">ll</span> <span class="nf">dist</span><span class="p">(</span><span class="k">const</span> <span class="n">pll</span><span class="o">&amp;</span> <span class="n">A</span><span class="p">,</span> <span class="k">const</span> <span class="n">pll</span><span class="o">&amp;</span> <span class="n">B</span><span class="p">);</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="n">ll</span> <span class="n">N</span><span class="p">,</span> <span class="n">W</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">N</span> <span class="o">&gt;&gt;</span> <span class="n">W</span><span class="p">;</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">pll</span><span class="o">&gt;</span> <span class="n">locations1</span><span class="p">(</span><span class="n">W</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">pll</span><span class="o">&gt;</span> <span class="n">locations2</span><span class="p">(</span><span class="n">W</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span> <span class="n">locations1</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span> <span class="n">locations2</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="n">N</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">W</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">locations1</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">first</span> <span class="o">&gt;&gt;</span> <span class="n">locations1</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">second</span><span class="p">;</span> <span class="n">locations2</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">locations1</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="p">}</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">pair</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">pll</span><span class="o">&gt;&gt;&gt;</span> <span class="n">dp</span><span class="p">(</span><span class="n">W</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">pair</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">pll</span><span class="o">&gt;&gt;</span><span class="p">(</span><span class="n">W</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">make_pair</span><span class="p">(</span><span class="mi">10'000'000LL</span><span class="p">,</span> <span class="n">make_pair</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">))));</span> <span class="n">dp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">].</span><span class="n">first</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">dp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">].</span><span class="n">second</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="n">dp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">].</span><span class="n">first</span> <span class="o">=</span> <span class="n">dist</span><span class="p">(</span><span class="n">make_pair</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="n">locations1</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span> <span class="n">dp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">].</span><span class="n">second</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">2</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">W</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">dp</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">0</span><span class="p">].</span><span class="n">first</span> <span class="o">=</span> <span class="n">dp</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">].</span><span class="n">first</span> <span class="o">+</span> <span class="n">dist</span><span class="p">(</span><span class="n">locations1</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">locations1</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span> <span class="n">dp</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">0</span><span class="p">].</span><span class="n">second</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="p">}</span> <span class="n">dp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">].</span><span class="n">first</span> <span class="o">=</span> <span class="n">dist</span><span class="p">(</span><span class="n">make_pair</span><span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="n">N</span><span class="p">),</span> <span class="n">locations2</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span> <span class="n">dp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">].</span><span class="n">second</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">2</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">W</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">dp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="n">i</span><span class="p">].</span><span class="n">first</span> <span class="o">=</span> <span class="n">dp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">].</span><span class="n">first</span> <span class="o">+</span> <span class="n">dist</span><span class="p">(</span><span class="n">locations2</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">locations2</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span> <span class="n">dp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="n">i</span><span class="p">].</span><span class="n">second</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span> <span class="p">}</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">sum</span><span class="o">=</span><span class="mi">3</span><span class="p">;</span> <span class="n">sum</span><span class="o">&lt;</span><span class="mi">2</span> <span class="o">*</span> <span class="n">W</span><span class="p">;</span> <span class="n">sum</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">first</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">first</span><span class="o">&lt;</span><span class="n">sum</span><span class="p">;</span> <span class="n">first</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">ll</span> <span class="n">second</span> <span class="o">=</span> <span class="n">sum</span> <span class="o">-</span> <span class="n">first</span><span class="p">;</span> <span class="k">if</span> <span class="p">(</span><span class="n">first</span> <span class="o">&gt;</span> <span class="n">W</span> <span class="o">||</span> <span class="n">second</span> <span class="o">&gt;</span> <span class="n">W</span><span class="p">)</span> <span class="p">{</span> <span class="k">continue</span><span class="p">;</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">first</span> <span class="o">&gt;</span> <span class="n">second</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">first</span> <span class="o">-</span> <span class="n">second</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">start</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">start</span><span class="o">&lt;=</span><span class="n">first</span><span class="o">-</span><span class="mi">2</span><span class="p">;</span> <span class="n">start</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">ll</span> <span class="n">candidate</span> <span class="o">=</span> <span class="n">dp</span><span class="p">[</span><span class="n">start</span><span class="p">][</span><span class="n">second</span><span class="p">].</span><span class="n">first</span> <span class="o">+</span> <span class="n">dist</span><span class="p">(</span><span class="n">locations1</span><span class="p">[</span><span class="n">start</span><span class="p">],</span> <span class="n">locations1</span><span class="p">[</span><span class="n">first</span><span class="p">]);</span> <span class="k">if</span> <span class="p">(</span><span class="n">dp</span><span class="p">[</span><span class="n">first</span><span class="p">][</span><span class="n">second</span><span class="p">].</span><span class="n">first</span> <span class="o">&gt;</span> <span class="n">candidate</span><span class="p">)</span> <span class="p">{</span> <span class="n">dp</span><span class="p">[</span><span class="n">first</span><span class="p">][</span><span class="n">second</span><span class="p">].</span><span class="n">first</span> <span class="o">=</span> <span class="n">candidate</span><span class="p">;</span> <span class="n">dp</span><span class="p">[</span><span class="n">first</span><span class="p">][</span><span class="n">second</span><span class="p">].</span><span class="n">second</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="n">start</span><span class="p">,</span> <span class="n">second</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">dp</span><span class="p">[</span><span class="n">first</span><span class="p">][</span><span class="n">second</span><span class="p">].</span><span class="n">first</span> <span class="o">=</span> <span class="n">dp</span><span class="p">[</span><span class="n">first</span><span class="o">-</span><span class="mi">1</span><span class="p">][</span><span class="n">second</span><span class="p">].</span><span class="n">first</span> <span class="o">+</span> <span class="n">dist</span><span class="p">(</span><span class="n">locations1</span><span class="p">[</span><span class="n">first</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">locations1</span><span class="p">[</span><span class="n">first</span><span class="p">]);</span> <span class="n">dp</span><span class="p">[</span><span class="n">first</span><span class="p">][</span><span class="n">second</span><span class="p">].</span><span class="n">second</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="n">first</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">second</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">first</span> <span class="o">&lt;</span> <span class="n">second</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">second</span> <span class="o">-</span> <span class="n">first</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">start</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">start</span><span class="o">&lt;=</span><span class="n">second</span><span class="o">-</span><span class="mi">2</span><span class="p">;</span> <span class="n">start</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">ll</span> <span class="n">candidate</span> <span class="o">=</span> <span class="n">dp</span><span class="p">[</span><span class="n">first</span><span class="p">][</span><span class="n">start</span><span class="p">].</span><span class="n">first</span> <span class="o">+</span> <span class="n">dist</span><span class="p">(</span><span class="n">locations2</span><span class="p">[</span><span class="n">start</span><span class="p">],</span> <span class="n">locations2</span><span class="p">[</span><span class="n">second</span><span class="p">]);</span> <span class="k">if</span> <span class="p">(</span><span class="n">dp</span><span class="p">[</span><span class="n">first</span><span class="p">][</span><span class="n">second</span><span class="p">].</span><span class="n">first</span> <span class="o">&gt;</span> <span class="n">candidate</span><span class="p">)</span> <span class="p">{</span> <span class="n">dp</span><span class="p">[</span><span class="n">first</span><span class="p">][</span><span class="n">second</span><span class="p">].</span><span class="n">first</span> <span class="o">=</span> <span class="n">candidate</span><span class="p">;</span> <span class="n">dp</span><span class="p">[</span><span class="n">first</span><span class="p">][</span><span class="n">second</span><span class="p">].</span><span class="n">second</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="n">first</span><span class="p">,</span> <span class="n">start</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">dp</span><span class="p">[</span><span class="n">first</span><span class="p">][</span><span class="n">second</span><span class="p">].</span><span class="n">first</span> <span class="o">=</span> <span class="n">dp</span><span class="p">[</span><span class="n">first</span><span class="p">][</span><span class="n">second</span><span class="o">-</span><span class="mi">1</span><span class="p">].</span><span class="n">first</span> <span class="o">+</span> <span class="n">dist</span><span class="p">(</span><span class="n">locations2</span><span class="p">[</span><span class="n">second</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">locations2</span><span class="p">[</span><span class="n">second</span><span class="p">]);</span> <span class="n">dp</span><span class="p">[</span><span class="n">first</span><span class="p">][</span><span class="n">second</span><span class="p">].</span><span class="n">second</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="n">first</span><span class="p">,</span> <span class="n">second</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="n">ll</span> <span class="n">minimum</span> <span class="o">=</span> <span class="n">LLONG_MAX</span><span class="p">;</span> <span class="n">pll</span> <span class="n">curr</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">W</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">minimum</span> <span class="o">&gt;</span> <span class="n">dp</span><span class="p">[</span><span class="n">W</span><span class="p">][</span><span class="n">i</span><span class="p">].</span><span class="n">first</span><span class="p">)</span> <span class="p">{</span> <span class="n">minimum</span> <span class="o">=</span> <span class="n">dp</span><span class="p">[</span><span class="n">W</span><span class="p">][</span><span class="n">i</span><span class="p">].</span><span class="n">first</span><span class="p">;</span> <span class="n">curr</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="n">W</span><span class="p">,</span> <span class="n">i</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">W</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">minimum</span> <span class="o">&gt;</span> <span class="n">dp</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">W</span><span class="p">].</span><span class="n">first</span><span class="p">)</span> <span class="p">{</span> <span class="n">minimum</span> <span class="o">=</span> <span class="n">dp</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">W</span><span class="p">].</span><span class="n">first</span><span class="p">;</span> <span class="n">curr</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">W</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="n">stack</span><span class="o">&lt;</span><span class="n">pll</span><span class="o">&gt;</span> <span class="n">s</span><span class="p">;</span> <span class="n">s</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">curr</span><span class="p">);</span> <span class="n">curr</span> <span class="o">=</span> <span class="n">dp</span><span class="p">[</span><span class="n">curr</span><span class="p">.</span><span class="n">first</span><span class="p">][</span><span class="n">curr</span><span class="p">.</span><span class="n">second</span><span class="p">].</span><span class="n">second</span><span class="p">;</span> <span class="k">while</span> <span class="p">(</span><span class="n">curr</span><span class="p">.</span><span class="n">first</span> <span class="o">!=</span> <span class="mi">0</span> <span class="o">||</span> <span class="n">curr</span><span class="p">.</span><span class="n">second</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="n">s</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">curr</span><span class="p">);</span> <span class="n">curr</span> <span class="o">=</span> <span class="n">dp</span><span class="p">[</span><span class="n">curr</span><span class="p">.</span><span class="n">first</span><span class="p">][</span><span class="n">curr</span><span class="p">.</span><span class="n">second</span><span class="p">].</span><span class="n">second</span><span class="p">;</span> <span class="p">}</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">minimum</span> <span class="o">&lt;&lt;</span> <span class="sc">'\n'</span><span class="p">;</span> <span class="n">ll</span> <span class="n">first</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">ll</span> <span class="n">second</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">s</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span> <span class="p">{</span> <span class="k">auto</span> <span class="n">curr</span> <span class="o">=</span> <span class="n">s</span><span class="p">.</span><span class="n">top</span><span class="p">();</span> <span class="n">s</span><span class="p">.</span><span class="n">pop</span><span class="p">();</span> <span class="k">if</span> <span class="p">(</span><span class="n">first</span> <span class="o">!=</span> <span class="n">curr</span><span class="p">.</span><span class="n">first</span><span class="p">)</span> <span class="p">{</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="mi">1</span> <span class="o">&lt;&lt;</span> <span class="sc">'\n'</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="mi">2</span> <span class="o">&lt;&lt;</span> <span class="sc">'\n'</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="n">ll</span> <span class="n">dist</span><span class="p">(</span><span class="k">const</span> <span class="n">pll</span><span class="o">&amp;</span> <span class="n">A</span><span class="p">,</span> <span class="k">const</span> <span class="n">pll</span><span class="o">&amp;</span> <span class="n">B</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="n">abs</span><span class="p">(</span><span class="n">A</span><span class="p">.</span><span class="n">first</span> <span class="o">-</span> <span class="n">B</span><span class="p">.</span><span class="n">first</span><span class="p">)</span> <span class="o">+</span> <span class="n">abs</span><span class="p">(</span><span class="n">A</span><span class="p">.</span><span class="n">second</span> <span class="o">-</span> <span class="n">B</span><span class="p">.</span><span class="n">second</span><span class="p">);</span> <span class="p">}</span> </code></pre></div></div> <p>실행 결과 ‘틀렸습니다’ 가 떴다.</p> <h3 id="2번째-시도">2번째 시도</h3> <p>질문 게시판의 반례들을 찾아 테스트 해본 결과, 거리는 정확하게 계산해냈지만 어떤 경찰차가 움직여야 하는지 제대로 추적하지 못하고 있었다.</p> <p>사용한 추적 방식은 DP 테이블을 업데이트 하는 과정에서 최소 값이 반영되기 위한 이전의 DP 테이블의 위치를 같이 저장해두는 것이었는데, DP 테이블 업데이트가 모두 끝나고 사건별 이동 경찰차를 추적하는 과정에서 다음에 확인해야 할 DP 테이블의 인덱스를 업데이트 해주지 않아 문제가 발생했던 것이다.</p> <p>코드는 다음과 같이 수정하였다.</p> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;bits/extc++.h&gt;</span><span class="cp"> </span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">__gnu_pbds</span><span class="p">;</span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">using</span> <span class="n">ll</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">long</span><span class="p">;</span> <span class="k">using</span> <span class="n">ull</span> <span class="o">=</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="kt">long</span><span class="p">;</span> <span class="k">using</span> <span class="n">ld</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">double</span><span class="p">;</span> <span class="k">using</span> <span class="n">pll</span> <span class="o">=</span> <span class="n">pair</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;</span><span class="p">;</span> <span class="n">ll</span> <span class="nf">dist</span><span class="p">(</span><span class="k">const</span> <span class="n">pll</span><span class="o">&amp;</span> <span class="n">A</span><span class="p">,</span> <span class="k">const</span> <span class="n">pll</span><span class="o">&amp;</span> <span class="n">B</span><span class="p">);</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="n">ll</span> <span class="n">N</span><span class="p">,</span> <span class="n">W</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">N</span> <span class="o">&gt;&gt;</span> <span class="n">W</span><span class="p">;</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">pll</span><span class="o">&gt;</span> <span class="n">locations1</span><span class="p">(</span><span class="n">W</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">pll</span><span class="o">&gt;</span> <span class="n">locations2</span><span class="p">(</span><span class="n">W</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span> <span class="n">locations1</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span> <span class="n">locations2</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="n">N</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">W</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">locations1</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">first</span> <span class="o">&gt;&gt;</span> <span class="n">locations1</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">second</span><span class="p">;</span> <span class="n">locations2</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">locations1</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="p">}</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">pair</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">pll</span><span class="o">&gt;&gt;&gt;</span> <span class="n">dp</span><span class="p">(</span><span class="n">W</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">pair</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">pll</span><span class="o">&gt;&gt;</span><span class="p">(</span><span class="n">W</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">make_pair</span><span class="p">(</span><span class="mi">10'000'000LL</span><span class="p">,</span> <span class="n">make_pair</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">))));</span> <span class="n">dp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">].</span><span class="n">first</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">dp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">].</span><span class="n">second</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="n">dp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">].</span><span class="n">first</span> <span class="o">=</span> <span class="n">dist</span><span class="p">(</span><span class="n">make_pair</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="n">locations1</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span> <span class="n">dp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">].</span><span class="n">second</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">2</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">W</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">dp</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">0</span><span class="p">].</span><span class="n">first</span> <span class="o">=</span> <span class="n">dp</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">].</span><span class="n">first</span> <span class="o">+</span> <span class="n">dist</span><span class="p">(</span><span class="n">locations1</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">locations1</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span> <span class="n">dp</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">0</span><span class="p">].</span><span class="n">second</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="p">}</span> <span class="n">dp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">].</span><span class="n">first</span> <span class="o">=</span> <span class="n">dist</span><span class="p">(</span><span class="n">make_pair</span><span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="n">N</span><span class="p">),</span> <span class="n">locations2</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span> <span class="n">dp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">].</span><span class="n">second</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">2</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">W</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">dp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="n">i</span><span class="p">].</span><span class="n">first</span> <span class="o">=</span> <span class="n">dp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">].</span><span class="n">first</span> <span class="o">+</span> <span class="n">dist</span><span class="p">(</span><span class="n">locations2</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">locations2</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span> <span class="n">dp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="n">i</span><span class="p">].</span><span class="n">second</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span> <span class="p">}</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">sum</span><span class="o">=</span><span class="mi">3</span><span class="p">;</span> <span class="n">sum</span><span class="o">&lt;</span><span class="mi">2</span> <span class="o">*</span> <span class="n">W</span><span class="p">;</span> <span class="n">sum</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">first</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">first</span><span class="o">&lt;</span><span class="n">sum</span><span class="p">;</span> <span class="n">first</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">ll</span> <span class="n">second</span> <span class="o">=</span> <span class="n">sum</span> <span class="o">-</span> <span class="n">first</span><span class="p">;</span> <span class="k">if</span> <span class="p">(</span><span class="n">first</span> <span class="o">&gt;</span> <span class="n">W</span> <span class="o">||</span> <span class="n">second</span> <span class="o">&gt;</span> <span class="n">W</span><span class="p">)</span> <span class="p">{</span> <span class="k">continue</span><span class="p">;</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">first</span> <span class="o">&gt;</span> <span class="n">second</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">first</span> <span class="o">-</span> <span class="n">second</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">start</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">start</span><span class="o">&lt;=</span><span class="n">first</span><span class="o">-</span><span class="mi">2</span><span class="p">;</span> <span class="n">start</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">ll</span> <span class="n">candidate</span> <span class="o">=</span> <span class="n">dp</span><span class="p">[</span><span class="n">start</span><span class="p">][</span><span class="n">second</span><span class="p">].</span><span class="n">first</span> <span class="o">+</span> <span class="n">dist</span><span class="p">(</span><span class="n">locations1</span><span class="p">[</span><span class="n">start</span><span class="p">],</span> <span class="n">locations1</span><span class="p">[</span><span class="n">first</span><span class="p">]);</span> <span class="k">if</span> <span class="p">(</span><span class="n">dp</span><span class="p">[</span><span class="n">first</span><span class="p">][</span><span class="n">second</span><span class="p">].</span><span class="n">first</span> <span class="o">&gt;</span> <span class="n">candidate</span><span class="p">)</span> <span class="p">{</span> <span class="n">dp</span><span class="p">[</span><span class="n">first</span><span class="p">][</span><span class="n">second</span><span class="p">].</span><span class="n">first</span> <span class="o">=</span> <span class="n">candidate</span><span class="p">;</span> <span class="n">dp</span><span class="p">[</span><span class="n">first</span><span class="p">][</span><span class="n">second</span><span class="p">].</span><span class="n">second</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="n">start</span><span class="p">,</span> <span class="n">second</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">dp</span><span class="p">[</span><span class="n">first</span><span class="p">][</span><span class="n">second</span><span class="p">].</span><span class="n">first</span> <span class="o">=</span> <span class="n">dp</span><span class="p">[</span><span class="n">first</span><span class="o">-</span><span class="mi">1</span><span class="p">][</span><span class="n">second</span><span class="p">].</span><span class="n">first</span> <span class="o">+</span> <span class="n">dist</span><span class="p">(</span><span class="n">locations1</span><span class="p">[</span><span class="n">first</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">locations1</span><span class="p">[</span><span class="n">first</span><span class="p">]);</span> <span class="n">dp</span><span class="p">[</span><span class="n">first</span><span class="p">][</span><span class="n">second</span><span class="p">].</span><span class="n">second</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="n">first</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">second</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">first</span> <span class="o">&lt;</span> <span class="n">second</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">second</span> <span class="o">-</span> <span class="n">first</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">start</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">start</span><span class="o">&lt;=</span><span class="n">second</span><span class="o">-</span><span class="mi">2</span><span class="p">;</span> <span class="n">start</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">ll</span> <span class="n">candidate</span> <span class="o">=</span> <span class="n">dp</span><span class="p">[</span><span class="n">first</span><span class="p">][</span><span class="n">start</span><span class="p">].</span><span class="n">first</span> <span class="o">+</span> <span class="n">dist</span><span class="p">(</span><span class="n">locations2</span><span class="p">[</span><span class="n">start</span><span class="p">],</span> <span class="n">locations2</span><span class="p">[</span><span class="n">second</span><span class="p">]);</span> <span class="k">if</span> <span class="p">(</span><span class="n">dp</span><span class="p">[</span><span class="n">first</span><span class="p">][</span><span class="n">second</span><span class="p">].</span><span class="n">first</span> <span class="o">&gt;</span> <span class="n">candidate</span><span class="p">)</span> <span class="p">{</span> <span class="n">dp</span><span class="p">[</span><span class="n">first</span><span class="p">][</span><span class="n">second</span><span class="p">].</span><span class="n">first</span> <span class="o">=</span> <span class="n">candidate</span><span class="p">;</span> <span class="n">dp</span><span class="p">[</span><span class="n">first</span><span class="p">][</span><span class="n">second</span><span class="p">].</span><span class="n">second</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="n">first</span><span class="p">,</span> <span class="n">start</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">dp</span><span class="p">[</span><span class="n">first</span><span class="p">][</span><span class="n">second</span><span class="p">].</span><span class="n">first</span> <span class="o">=</span> <span class="n">dp</span><span class="p">[</span><span class="n">first</span><span class="p">][</span><span class="n">second</span><span class="o">-</span><span class="mi">1</span><span class="p">].</span><span class="n">first</span> <span class="o">+</span> <span class="n">dist</span><span class="p">(</span><span class="n">locations2</span><span class="p">[</span><span class="n">second</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">locations2</span><span class="p">[</span><span class="n">second</span><span class="p">]);</span> <span class="n">dp</span><span class="p">[</span><span class="n">first</span><span class="p">][</span><span class="n">second</span><span class="p">].</span><span class="n">second</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="n">first</span><span class="p">,</span> <span class="n">second</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="n">ll</span> <span class="n">minimum</span> <span class="o">=</span> <span class="n">LLONG_MAX</span><span class="p">;</span> <span class="n">pll</span> <span class="n">curr</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">W</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">minimum</span> <span class="o">&gt;</span> <span class="n">dp</span><span class="p">[</span><span class="n">W</span><span class="p">][</span><span class="n">i</span><span class="p">].</span><span class="n">first</span><span class="p">)</span> <span class="p">{</span> <span class="n">minimum</span> <span class="o">=</span> <span class="n">dp</span><span class="p">[</span><span class="n">W</span><span class="p">][</span><span class="n">i</span><span class="p">].</span><span class="n">first</span><span class="p">;</span> <span class="n">curr</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="n">W</span><span class="p">,</span> <span class="n">i</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">W</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">minimum</span> <span class="o">&gt;</span> <span class="n">dp</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">W</span><span class="p">].</span><span class="n">first</span><span class="p">)</span> <span class="p">{</span> <span class="n">minimum</span> <span class="o">=</span> <span class="n">dp</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">W</span><span class="p">].</span><span class="n">first</span><span class="p">;</span> <span class="n">curr</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">W</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="n">stack</span><span class="o">&lt;</span><span class="n">pll</span><span class="o">&gt;</span> <span class="n">s</span><span class="p">;</span> <span class="n">s</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">curr</span><span class="p">);</span> <span class="n">curr</span> <span class="o">=</span> <span class="n">dp</span><span class="p">[</span><span class="n">curr</span><span class="p">.</span><span class="n">first</span><span class="p">][</span><span class="n">curr</span><span class="p">.</span><span class="n">second</span><span class="p">].</span><span class="n">second</span><span class="p">;</span> <span class="k">while</span> <span class="p">(</span><span class="n">curr</span><span class="p">.</span><span class="n">first</span> <span class="o">!=</span> <span class="mi">0</span> <span class="o">||</span> <span class="n">curr</span><span class="p">.</span><span class="n">second</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="n">s</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">curr</span><span class="p">);</span> <span class="n">curr</span> <span class="o">=</span> <span class="n">dp</span><span class="p">[</span><span class="n">curr</span><span class="p">.</span><span class="n">first</span><span class="p">][</span><span class="n">curr</span><span class="p">.</span><span class="n">second</span><span class="p">].</span><span class="n">second</span><span class="p">;</span> <span class="p">}</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">minimum</span> <span class="o">&lt;&lt;</span> <span class="sc">'\n'</span><span class="p">;</span> <span class="n">ll</span> <span class="n">first</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">ll</span> <span class="n">second</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">s</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span> <span class="p">{</span> <span class="k">auto</span> <span class="n">curr</span> <span class="o">=</span> <span class="n">s</span><span class="p">.</span><span class="n">top</span><span class="p">();</span> <span class="n">s</span><span class="p">.</span><span class="n">pop</span><span class="p">();</span> <span class="k">if</span> <span class="p">(</span><span class="n">first</span> <span class="o">!=</span> <span class="n">curr</span><span class="p">.</span><span class="n">first</span><span class="p">)</span> <span class="p">{</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="mi">1</span> <span class="o">&lt;&lt;</span> <span class="sc">'\n'</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="mi">2</span> <span class="o">&lt;&lt;</span> <span class="sc">'\n'</span><span class="p">;</span> <span class="p">}</span> <span class="n">first</span> <span class="o">=</span> <span class="n">curr</span><span class="p">.</span><span class="n">first</span><span class="p">;</span> <span class="n">second</span> <span class="o">=</span> <span class="n">curr</span><span class="p">.</span><span class="n">second</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="n">ll</span> <span class="n">dist</span><span class="p">(</span><span class="k">const</span> <span class="n">pll</span><span class="o">&amp;</span> <span class="n">A</span><span class="p">,</span> <span class="k">const</span> <span class="n">pll</span><span class="o">&amp;</span> <span class="n">B</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="n">abs</span><span class="p">(</span><span class="n">A</span><span class="p">.</span><span class="n">first</span> <span class="o">-</span> <span class="n">B</span><span class="p">.</span><span class="n">first</span><span class="p">)</span> <span class="o">+</span> <span class="n">abs</span><span class="p">(</span><span class="n">A</span><span class="p">.</span><span class="n">second</span> <span class="o">-</span> <span class="n">B</span><span class="p">.</span><span class="n">second</span><span class="p">);</span> <span class="p">}</span> </code></pre></div></div> <p>그러자 모든 테스트 케이스를 통과하고 ‘맞았습니다’가 나오는 것을 확인할 수 있었다.</p> <h2 id="마무리">마무리</h2> <p>꽤 오랜 시간 동안 솔브드 클래스 문제를 풀지 않았다. CLASS 문제를 미는 이 과정에 회의가 들었기 때문이다.</p> <p>최근에는 수학을 제일 많이 공부했지만, 어디까지나 최대 관심사는 AI 이다. 수학을 심도있게 공부하는 것도 AI 연구를 위한 것이다. 그러나, CLASS 문제들을 미는 것이 과연 AI 연구에 큰 도움이 되는가 하는 생각이 들기 시작했다.</p> <p>솔직히 CLASS 6 이상의 문제들은 프로그래머로써 알아야 할 기본적인 알고리즘의 범위를 벗어나는 것들을 다룬다고 생각한다. 그렇기 때문에 다른 공부 시간을 깎아가며 무리하게 CLASS 문제들이 비교적 불필요하게 느껴졌고, 한 동안 CLASS 문제들을 푸는 것을 중단했다. 그냥 매일 브론즈 5~3 정도 난이도의 쉬운 문제들만 풀어 스트릭만 간신히 이어가는 방식으로 가볍게 맥을 이어오고 있었다.</p> <p>그러다 훈련 때문에 한 번 스트릭이 끊어진 적이 있었다. 그 이후로는 군대 내에서 스트릭이 큰 의미가 있나 하는 생각이 들었고, 최근 들어서는 스트릭에 전혀 신경을 쓰지 않게 되었다. 길어봐야 10분이면 다 푸는 간단한 문제들을 기계적으로 푸는데 지쳤기 때문이다.</p> <p>그래서 앞으로는 스트릭은 신경끄고 CLASS 문제들을 미는데 코딩 공부 시간을 쓰기로 했다. 단, 앞서 이야기 한 것처럼 주 관심 분야인 AI 와는 거리가 있는 내용들을 다루고 있기 때문에 풀다가 잘 안되면 중단하고 다른 할 일을 하고, 다음 날 다시 시도해보는 방식으로 진행할 것 같다. 오늘 풀어 낸 2618번 문제가 그런 방식으로 풀린 첫 번째 문제였다.</p> <p>문제 자체에 대한 이야기를 하자면, 습격자 초라기 정도는 아니었지만 꽤 머리 좀 써야 했던 골치아픈 DP 문제였던 것 같다. DP 테이블 구성 방식이나 점화식에 대한 아이디어를 떠올리는 것은 비교적 수월했지만, 그걸 코딩으로 구현하는게 조금 까다로웠던 것 같다. 확실히 CLASS 6 의 DP 문제는 격이 다르다는 걸 떠올리게 해주는 문제였다.</p> <p>오늘의 PS는 여기까지!</p> <hr /> <p><a name="footnote_1">1</a>: <a href="https://www.acmicpc.net/problem/2618">https://www.acmicpc.net/problem/2618</a></p> Sat, 25 Jan 2025 23:59:00 +0900 https://choicube84.github.io/study/2025/01/25/baekjoon_2618.html https://choicube84.github.io/study/2025/01/25/baekjoon_2618.html problem_solving Study 백준 5719번 <h1 id="백준-5719번">백준 5719번</h1> <p>오늘 풀어본 문제는 백준의 5719번 문제<sup><a href="#footnote_1">1</a></sup>이다. 문제 풀이에 사용한 언어는 C++ 이다.</p> <h2 id="solvedac-기준-class">solved.ac 기준 CLASS</h2> <p><img src="https://static.solved.ac/class/c6.svg" width="50%" height="50%" alt="CLASS 6" /></p> <h2 id="문제-정보">문제 정보</h2> <p>이 문제의 내용과 조건은 다음과 같다.</p> <h3 id="문제">문제</h3> <p>요즘 많은 자동차에서는 GPS 네비게이션 장비가 설치되어 있다. 네비게이션은 사용자가 입력한 출발점과 도착점 사이의 최단 경로를 검색해 준다. 하지만, 교통 상황을 고려하지 않고 최단 경로를 검색하는 경우에는 극심한 교통 정체를 경험할 수 있다.</p> <p>상근이는 오직 자기 자신만 사용 가능한 네비게이션을 만들고 있다. 이 네비게이션은 절대로 최단 경로를 찾아주지 않는다. 항상 거의 최단 경로를 찾아준다.</p> <p>거의 최단 경로란 최단 경로에 포함되지 않는 도로로만 이루어진 경로 중 가장 짧은 것을 말한다.</p> <p>예를 들어, 도로 지도가 아래와 같을 때를 생각해보자. 원은 장소를 의미하고, 선은 단방향 도로를 나타낸다. 시작점은 $S$, 도착점은 $D$ 로 표시되어 있다. 굵은 선은 최단 경로를 나타낸다. (아래 그림에 최단 경로는 두 개가 있다)거의 최단 경로는 점선으로 표시된 경로이다. 이 경로는 최단 경로에 포함되지 않은 도로로 이루어진 경로 중 가장 짧은 경로이다. 거의 최단 경로는 여러 개 존재할 수도 있다. 예를 들어, 아래 그림의 길이가 $3$ 인 도로의 길이가 $1$ 이라면, 거의 최단 경로는 두 개가 된다. 또, 거의 최단 경로가 없는 경우도 있다.</p> <p><img src="https://www.acmicpc.net/upload/images/almost.png" width="50%" height="50%" alt="map of road" /></p> <h3 id="입력">입력</h3> <p>입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스의 첫째 줄에는 장소의 수 $N$ $(2 \le N \le 500)과 도로의 수 M (1 \le M \le 10^4)가 주어진다. 장소는 $0$ 부터 $N-1$ 번까지 번호가 매겨져 있다. 둘째 줄에는 시작점 $S$ 와 도착점 $D$ 가 주어진다. $(S \neq D ; 0 \le S, D &lt; N)$ 다음 $M$ 개 줄에는 도로의 정보 $U$, $V$, $P$ 가 주어진다. $(U \neq V ; 0 \le U, V &lt; N; 1 \le P \le 10^3)$ 이 뜻은 $U$ 에서 $V$ 로 가는 도로의 길이가 $P$ 라는 뜻이다. $U$ 에서 $V$ 로 가는 도로는 최대 한 개이다. 또, $U$ 에서 $V$ 로 가는 도로와 $V$ 에서 $U$ 로 가는 도로는 다른 도로이다.</p> <p>입력의 마지막 줄에는 $0$ 이 두 개 주어진다.</p> <h3 id="출력">출력</h3> <p>각 테스트 케이스에 대해서, 거의 최단 경로의 길이를 출력한다. 만약, 거의 최단 경로가 없는 경우에는 $-1$ 을 출력한다.</p> <h2 id="풀이과정">풀이과정</h2> <h3 id="1번째-시도">1번째 시도</h3> <p>문제를 해결하기 위해 사용한 방식은 다음과 같다.</p> <ol> <li> <p>그래프의 정보를 입력받고, 다익스트라 알고리즘을 이용하여 최단 경로의 길이를 알아낸다.</p> </li> <li> <p>시작점에서부터 깊이 우선 탐색을 통해 도착점까지의 거리가 최단 경로와 일치하는 간선들을 제거한다.</p> </li> <li> <p>간선들이 제거된 그래프에서 다시 한 번 다익스트라 알고리즘을 사용하여 ‘거의 최단경로’의 길이를 알아낸다.</p> </li> </ol> <p>코드는 다음과 같이 작성하였다. 제출할 때는 헤더파일의 코드를 붙여넣어 제출하였다.</p> <h4 id="custom_algorithmshpp-일부분">custom_algorithms.hpp (일부분)</h4> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">namespace</span> <span class="n">dijkstra</span> <span class="p">{</span> <span class="k">template</span> <span class="o">&lt;</span><span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span><span class="p">,</span> <span class="k">typename</span><span class="p">&gt;</span> <span class="k">typename</span> <span class="nc">Table</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">Node</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">Distance</span><span class="p">&gt;</span> <span class="n">Table</span><span class="o">&lt;</span><span class="n">Node</span><span class="p">,</span> <span class="n">Distance</span><span class="o">&gt;</span> <span class="n">getShortestPath</span><span class="p">(</span><span class="n">Table</span><span class="o">&lt;</span><span class="n">Node</span><span class="p">,</span> <span class="n">Table</span><span class="o">&lt;</span><span class="n">Node</span><span class="p">,</span> <span class="n">Distance</span><span class="o">&gt;&gt;&amp;</span> <span class="n">graph</span><span class="p">,</span> <span class="k">const</span> <span class="n">Node</span><span class="o">&amp;</span> <span class="n">start</span><span class="p">)</span> <span class="p">{</span> <span class="n">Table</span><span class="o">&lt;</span><span class="n">Node</span><span class="p">,</span> <span class="n">Distance</span><span class="o">&gt;</span> <span class="n">distance</span><span class="p">;</span> <span class="n">distance</span><span class="p">[</span><span class="n">start</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="k">struct</span> <span class="nc">cmp</span> <span class="p">{</span> <span class="kt">bool</span> <span class="k">operator</span><span class="p">()(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o">&lt;</span><span class="n">Node</span><span class="p">,</span> <span class="n">Distance</span><span class="o">&gt;&amp;</span> <span class="n">a</span><span class="p">,</span> <span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o">&lt;</span><span class="n">Node</span><span class="p">,</span> <span class="n">Distance</span><span class="o">&gt;&amp;</span> <span class="n">b</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="n">a</span><span class="p">.</span><span class="n">second</span> <span class="o">&gt;</span> <span class="n">b</span><span class="p">.</span><span class="n">second</span><span class="p">;</span> <span class="p">}</span> <span class="p">};</span> <span class="n">std</span><span class="o">::</span><span class="n">priority_queue</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o">&lt;</span><span class="n">Node</span><span class="p">,</span> <span class="n">Distance</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o">&lt;</span><span class="n">Node</span><span class="p">,</span> <span class="n">Distance</span><span class="o">&gt;&gt;</span><span class="p">,</span> <span class="n">cmp</span><span class="o">&gt;</span> <span class="n">pq</span><span class="p">;</span> <span class="n">pq</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">make_pair</span><span class="p">(</span><span class="n">start</span><span class="p">,</span> <span class="mi">0</span><span class="p">));</span> <span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">pq</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span> <span class="p">{</span> <span class="k">auto</span> <span class="p">[</span><span class="n">currNode</span><span class="p">,</span> <span class="n">currDist</span><span class="p">]</span> <span class="o">=</span> <span class="n">pq</span><span class="p">.</span><span class="n">top</span><span class="p">();</span> <span class="n">pq</span><span class="p">.</span><span class="n">pop</span><span class="p">();</span> <span class="k">if</span> <span class="p">(</span><span class="n">distance</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">currNode</span><span class="p">)</span> <span class="o">!=</span> <span class="n">distance</span><span class="p">.</span><span class="n">end</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="n">distance</span><span class="p">[</span><span class="n">currNode</span><span class="p">]</span> <span class="o">&lt;</span> <span class="n">currDist</span><span class="p">)</span> <span class="p">{</span> <span class="k">continue</span><span class="p">;</span> <span class="p">}</span> <span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="p">[</span><span class="n">next</span><span class="p">,</span> <span class="n">weight</span><span class="p">]</span> <span class="o">:</span> <span class="n">graph</span><span class="p">[</span><span class="n">currNode</span><span class="p">])</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">weight</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="n">distance</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span> <span class="k">return</span> <span class="n">distance</span><span class="p">;</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">distance</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">next</span><span class="p">)</span> <span class="o">==</span> <span class="n">distance</span><span class="p">.</span><span class="n">end</span><span class="p">()</span> <span class="o">||</span> <span class="n">distance</span><span class="p">[</span><span class="n">next</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">currDist</span> <span class="o">+</span> <span class="n">weight</span><span class="p">)</span> <span class="p">{</span> <span class="n">distance</span><span class="p">[</span><span class="n">next</span><span class="p">]</span> <span class="o">=</span> <span class="n">currDist</span> <span class="o">+</span> <span class="n">weight</span><span class="p">;</span> <span class="n">pq</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">make_pair</span><span class="p">(</span><span class="n">next</span><span class="p">,</span> <span class="n">distance</span><span class="p">[</span><span class="n">next</span><span class="p">]));</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="k">return</span> <span class="n">distance</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <h4 id="maincpp">main.cpp</h4> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;bits/extc++.h&gt;</span><span class="cp"> #include</span> <span class="cpf">"custom_algorithms.hpp"</span><span class="cp"> </span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">__gnu_pbds</span><span class="p">;</span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">custom_algorithms</span><span class="p">;</span> <span class="k">using</span> <span class="n">ll</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">ull</span> <span class="o">=</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">ld</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">double</span><span class="p">;</span> <span class="k">using</span> <span class="n">pll</span> <span class="o">=</span> <span class="n">pair</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;</span><span class="p">;</span> <span class="kt">bool</span> <span class="nf">solve</span><span class="p">(</span><span class="kt">void</span><span class="p">);</span> <span class="kt">bool</span> <span class="nf">RemoveShortestPaths</span><span class="p">(</span><span class="n">gp_hash_table</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">gp_hash_table</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;&gt;&amp;</span> <span class="n">table</span><span class="p">,</span> <span class="n">ll</span> <span class="n">curr</span><span class="p">,</span> <span class="n">ll</span> <span class="n">dest</span><span class="p">,</span> <span class="n">ll</span> <span class="n">depth</span><span class="p">);</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="k">while</span> <span class="p">(</span><span class="n">solve</span><span class="p">());</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="kt">bool</span> <span class="n">solve</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">ll</span> <span class="n">N</span><span class="p">,</span> <span class="n">M</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">N</span> <span class="o">&gt;&gt;</span> <span class="n">M</span><span class="p">;</span> <span class="k">if</span> <span class="p">(</span><span class="n">N</span> <span class="o">==</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">M</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nb">false</span><span class="p">;</span> <span class="p">}</span> <span class="n">ll</span> <span class="n">S</span><span class="p">,</span> <span class="n">D</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">S</span> <span class="o">&gt;&gt;</span> <span class="n">D</span><span class="p">;</span> <span class="n">gp_hash_table</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">gp_hash_table</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;&gt;</span> <span class="n">table</span><span class="p">;</span> <span class="k">while</span> <span class="p">(</span><span class="n">M</span><span class="o">--</span><span class="p">)</span> <span class="p">{</span> <span class="n">ll</span> <span class="n">U</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">P</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">U</span> <span class="o">&gt;&gt;</span> <span class="n">V</span> <span class="o">&gt;&gt;</span> <span class="n">P</span><span class="p">;</span> <span class="n">table</span><span class="p">[</span><span class="n">U</span><span class="p">][</span><span class="n">V</span><span class="p">]</span> <span class="o">=</span> <span class="n">P</span><span class="p">;</span> <span class="p">}</span> <span class="k">auto</span> <span class="n">result</span> <span class="o">=</span> <span class="n">shortest_path</span><span class="o">::</span><span class="n">dijkstra</span><span class="o">::</span><span class="n">getShortestPath</span><span class="p">(</span><span class="n">table</span><span class="p">,</span> <span class="n">S</span><span class="p">);</span> <span class="n">RemoveShortestPaths</span><span class="p">(</span><span class="n">table</span><span class="p">,</span> <span class="n">S</span><span class="p">,</span> <span class="n">D</span><span class="p">,</span> <span class="n">result</span><span class="p">[</span><span class="n">D</span><span class="p">]);</span> <span class="n">result</span> <span class="o">=</span> <span class="n">shortest_path</span><span class="o">::</span><span class="n">dijkstra</span><span class="o">::</span><span class="n">getShortestPath</span><span class="p">(</span><span class="n">table</span><span class="p">,</span> <span class="n">S</span><span class="p">);</span> <span class="k">if</span> <span class="p">(</span><span class="n">result</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">D</span><span class="p">)</span> <span class="o">==</span> <span class="n">result</span><span class="p">.</span><span class="n">end</span><span class="p">())</span> <span class="p">{</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="o">-</span><span class="mi">1</span> <span class="o">&lt;&lt;</span> <span class="sc">'\n'</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">result</span><span class="p">[</span><span class="n">D</span><span class="p">]</span> <span class="o">&lt;&lt;</span> <span class="sc">'\n'</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="nb">true</span><span class="p">;</span> <span class="p">}</span> <span class="kt">bool</span> <span class="n">RemoveShortestPaths</span><span class="p">(</span><span class="n">gp_hash_table</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">gp_hash_table</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;&gt;&amp;</span> <span class="n">table</span><span class="p">,</span> <span class="n">ll</span> <span class="n">curr</span><span class="p">,</span> <span class="n">ll</span> <span class="n">dest</span><span class="p">,</span> <span class="n">ll</span> <span class="n">depth</span><span class="p">)</span> <span class="p">{</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;</span> <span class="n">nodes_to_disconnect</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="k">auto</span><span class="o">&amp;</span> <span class="p">[</span><span class="n">next</span><span class="p">,</span> <span class="n">length</span><span class="p">]</span> <span class="o">:</span> <span class="n">table</span><span class="p">[</span><span class="n">curr</span><span class="p">])</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">length</span> <span class="o">==</span> <span class="n">depth</span> <span class="o">&amp;&amp;</span> <span class="n">next</span> <span class="o">==</span> <span class="n">dest</span><span class="p">)</span> <span class="p">{</span> <span class="n">nodes_to_disconnect</span><span class="p">.</span><span class="n">emplace_back</span><span class="p">(</span><span class="n">next</span><span class="p">);</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">depth</span> <span class="o">&gt;</span> <span class="n">length</span><span class="p">)</span> <span class="p">{</span> <span class="kt">bool</span> <span class="n">search_result</span> <span class="o">=</span> <span class="n">RemoveShortestPaths</span><span class="p">(</span><span class="n">table</span><span class="p">,</span> <span class="n">next</span><span class="p">,</span> <span class="n">dest</span><span class="p">,</span> <span class="n">depth</span> <span class="o">-</span> <span class="n">length</span><span class="p">);</span> <span class="k">if</span> <span class="p">(</span><span class="n">search_result</span> <span class="o">==</span> <span class="nb">true</span><span class="p">)</span> <span class="p">{</span> <span class="n">nodes_to_disconnect</span><span class="p">.</span><span class="n">emplace_back</span><span class="p">(</span><span class="n">next</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">nodes_to_disconnect</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span> <span class="p">{</span> <span class="k">return</span> <span class="nb">false</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="k">auto</span><span class="o">&amp;</span> <span class="n">next</span> <span class="o">:</span> <span class="n">nodes_to_disconnect</span><span class="p">)</span> <span class="p">{</span> <span class="n">table</span><span class="p">[</span><span class="n">curr</span><span class="p">].</span><span class="n">erase</span><span class="p">(</span><span class="n">next</span><span class="p">);</span> <span class="p">}</span> <span class="k">return</span> <span class="nb">true</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>실행 결과 ‘시간 초과’ 가 떴다.</p> <h3 id="2-3번째-시도">2, 3번째 시도</h3> <p>‘시간 초과’의 발생 원인으로 우선 생각한 것은 중복된 방문이었고, 이를 해결해주기 위해 어떤 노드를 이미 방문하였는지 저장하는 <code class="language-plaintext highlighter-rouge">visited</code> 변수를 추가해주었다.</p> <p>코드를 처음 수정할 때 <code class="language-plaintext highlighter-rouge">RemoveShortestPaths</code> 함수의 인자 입력 방식이 바뀌었는데 함수를 사용할 때 이를 제대로 반영하지 않아 2번째 실행 결과로 ‘컴파일 에러’를 받았고, 3번째 시도에서는 이를 제대로 수정하였다.</p> <p>코드는 <code class="language-plaintext highlighter-rouge">main.cpp</code> 파일만 다음과 같이 수정하였다.</p> <h4 id="maincpp-1">main.cpp</h4> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;bits/extc++.h&gt;</span><span class="cp"> #include</span> <span class="cpf">"custom_algorithms.hpp"</span><span class="cp"> </span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">__gnu_pbds</span><span class="p">;</span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">custom_algorithms</span><span class="p">;</span> <span class="k">using</span> <span class="n">ll</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">ull</span> <span class="o">=</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">ld</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">double</span><span class="p">;</span> <span class="k">using</span> <span class="n">pll</span> <span class="o">=</span> <span class="n">pair</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;</span><span class="p">;</span> <span class="kt">bool</span> <span class="nf">solve</span><span class="p">(</span><span class="kt">void</span><span class="p">);</span> <span class="kt">bool</span> <span class="nf">RemoveShortestPaths</span><span class="p">(</span><span class="n">gp_hash_table</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">gp_hash_table</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;&gt;&amp;</span> <span class="n">table</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;&amp;</span> <span class="n">visited</span><span class="p">,</span> <span class="n">ll</span> <span class="n">curr</span><span class="p">,</span> <span class="n">ll</span> <span class="n">dest</span><span class="p">,</span> <span class="n">ll</span> <span class="n">depth</span><span class="p">);</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="k">while</span> <span class="p">(</span><span class="n">solve</span><span class="p">());</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="kt">bool</span> <span class="n">solve</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">ll</span> <span class="n">N</span><span class="p">,</span> <span class="n">M</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">N</span> <span class="o">&gt;&gt;</span> <span class="n">M</span><span class="p">;</span> <span class="k">if</span> <span class="p">(</span><span class="n">N</span> <span class="o">==</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">M</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nb">false</span><span class="p">;</span> <span class="p">}</span> <span class="n">ll</span> <span class="n">S</span><span class="p">,</span> <span class="n">D</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">S</span> <span class="o">&gt;&gt;</span> <span class="n">D</span><span class="p">;</span> <span class="n">gp_hash_table</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">gp_hash_table</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;&gt;</span> <span class="n">table</span><span class="p">;</span> <span class="k">while</span> <span class="p">(</span><span class="n">M</span><span class="o">--</span><span class="p">)</span> <span class="p">{</span> <span class="n">ll</span> <span class="n">U</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">P</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">U</span> <span class="o">&gt;&gt;</span> <span class="n">V</span> <span class="o">&gt;&gt;</span> <span class="n">P</span><span class="p">;</span> <span class="n">table</span><span class="p">[</span><span class="n">U</span><span class="p">][</span><span class="n">V</span><span class="p">]</span> <span class="o">=</span> <span class="n">P</span><span class="p">;</span> <span class="p">}</span> <span class="k">auto</span> <span class="n">result</span> <span class="o">=</span> <span class="n">shortest_path</span><span class="o">::</span><span class="n">dijkstra</span><span class="o">::</span><span class="n">getShortestPath</span><span class="p">(</span><span class="n">table</span><span class="p">,</span> <span class="n">S</span><span class="p">);</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;</span> <span class="n">visited</span><span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="nb">false</span><span class="p">);</span> <span class="n">RemoveShortestPaths</span><span class="p">(</span><span class="n">table</span><span class="p">,</span> <span class="n">visited</span><span class="p">,</span> <span class="n">S</span><span class="p">,</span> <span class="n">D</span><span class="p">,</span> <span class="n">result</span><span class="p">[</span><span class="n">D</span><span class="p">]);</span> <span class="n">result</span> <span class="o">=</span> <span class="n">shortest_path</span><span class="o">::</span><span class="n">dijkstra</span><span class="o">::</span><span class="n">getShortestPath</span><span class="p">(</span><span class="n">table</span><span class="p">,</span> <span class="n">S</span><span class="p">);</span> <span class="k">if</span> <span class="p">(</span><span class="n">result</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">D</span><span class="p">)</span> <span class="o">==</span> <span class="n">result</span><span class="p">.</span><span class="n">end</span><span class="p">())</span> <span class="p">{</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="o">-</span><span class="mi">1</span> <span class="o">&lt;&lt;</span> <span class="sc">'\n'</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">result</span><span class="p">[</span><span class="n">D</span><span class="p">]</span> <span class="o">&lt;&lt;</span> <span class="sc">'\n'</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="nb">true</span><span class="p">;</span> <span class="p">}</span> <span class="kt">bool</span> <span class="n">RemoveShortestPaths</span><span class="p">(</span><span class="n">gp_hash_table</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">gp_hash_table</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;&gt;&amp;</span> <span class="n">table</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;&amp;</span> <span class="n">visited</span><span class="p">,</span> <span class="n">ll</span> <span class="n">curr</span><span class="p">,</span> <span class="n">ll</span> <span class="n">dest</span><span class="p">,</span> <span class="n">ll</span> <span class="n">depth</span><span class="p">)</span> <span class="p">{</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;</span> <span class="n">nodes_to_disconnect</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="k">auto</span><span class="o">&amp;</span> <span class="p">[</span><span class="n">next</span><span class="p">,</span> <span class="n">length</span><span class="p">]</span> <span class="o">:</span> <span class="n">table</span><span class="p">[</span><span class="n">curr</span><span class="p">])</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">visited</span><span class="p">[</span><span class="n">next</span><span class="p">]</span> <span class="o">==</span> <span class="nb">true</span><span class="p">)</span> <span class="p">{</span> <span class="k">continue</span><span class="p">;</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">length</span> <span class="o">==</span> <span class="n">depth</span> <span class="o">&amp;&amp;</span> <span class="n">next</span> <span class="o">==</span> <span class="n">dest</span><span class="p">)</span> <span class="p">{</span> <span class="n">visited</span><span class="p">[</span><span class="n">curr</span><span class="p">]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span> <span class="n">nodes_to_disconnect</span><span class="p">.</span><span class="n">emplace_back</span><span class="p">(</span><span class="n">next</span><span class="p">);</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">depth</span> <span class="o">&gt;</span> <span class="n">length</span><span class="p">)</span> <span class="p">{</span> <span class="kt">bool</span> <span class="n">search_result</span> <span class="o">=</span> <span class="n">RemoveShortestPaths</span><span class="p">(</span><span class="n">table</span><span class="p">,</span> <span class="n">visited</span><span class="p">,</span> <span class="n">next</span><span class="p">,</span> <span class="n">dest</span><span class="p">,</span> <span class="n">depth</span> <span class="o">-</span> <span class="n">length</span><span class="p">);</span> <span class="k">if</span> <span class="p">(</span><span class="n">search_result</span> <span class="o">==</span> <span class="nb">true</span><span class="p">)</span> <span class="p">{</span> <span class="n">visited</span><span class="p">[</span><span class="n">curr</span><span class="p">]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span> <span class="n">nodes_to_disconnect</span><span class="p">.</span><span class="n">emplace_back</span><span class="p">(</span><span class="n">next</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">nodes_to_disconnect</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span> <span class="p">{</span> <span class="k">return</span> <span class="nb">false</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="k">auto</span><span class="o">&amp;</span> <span class="n">next</span> <span class="o">:</span> <span class="n">nodes_to_disconnect</span><span class="p">)</span> <span class="p">{</span> <span class="n">table</span><span class="p">[</span><span class="n">curr</span><span class="p">].</span><span class="n">erase</span><span class="p">(</span><span class="n">next</span><span class="p">);</span> <span class="p">}</span> <span class="k">return</span> <span class="nb">true</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>실행 결과 ‘틀렸습니다’ 가 떴다.</p> <h3 id="4번째-시도">4번째 시도</h3> <p>질문 게시판에 올라온 여러 가지 테스트 케이스들을 테스트 해본 결과, 간선을 마지막에 제거하는 것이 아닌 탐색 과정중에 제거하기 때문에 일부 간선이 제대로 제거되지 않는 경우가 있었다.</p> <p>이에 새롭게 이용하기로한 해결 방식은 도착점에서 역으로 추적을 해나가는 것이었다. 내가 만든 다익스트라 알고리즘은 시작점에서 다른 모든 정점까지의 최단 경로의 길이를 저장한 테이블을 반환하기 때문에 갈 필요없는 정점에 대해서는 탐색하지 않을 것이고, 역방향 그래프에서 탐색을 진행하기 때문에 원래 그래프를 즉각적으로 수정해도 놓치게 되는 간선이 없을 것이라고 생각했다.</p> <p>코드는 <code class="language-plaintext highlighter-rouge">main.cpp</code> 파일만 다음과 같이 수정하였다.</p> <h4 id="maincpp-2">main.cpp</h4> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;bits/extc++.h&gt;</span><span class="cp"> #include</span> <span class="cpf">"custom_algorithms.hpp"</span><span class="cp"> </span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">__gnu_pbds</span><span class="p">;</span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">custom_algorithms</span><span class="p">;</span> <span class="k">using</span> <span class="n">ll</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">ull</span> <span class="o">=</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">ld</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">double</span><span class="p">;</span> <span class="k">using</span> <span class="n">pll</span> <span class="o">=</span> <span class="n">pair</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;</span><span class="p">;</span> <span class="k">using</span> <span class="n">Graph</span> <span class="o">=</span> <span class="n">gp_hash_table</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">gp_hash_table</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;&gt;</span><span class="p">;</span> <span class="kt">bool</span> <span class="nf">solve</span><span class="p">(</span><span class="kt">void</span><span class="p">);</span> <span class="kt">void</span> <span class="nf">RemoveShortestPaths</span><span class="p">(</span><span class="n">Graph</span><span class="o">&amp;</span> <span class="n">graph</span><span class="p">,</span> <span class="n">Graph</span><span class="o">&amp;</span> <span class="n">reversed_graph</span><span class="p">,</span> <span class="n">gp_hash_table</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;&amp;</span> <span class="n">dist</span><span class="p">,</span> <span class="n">ll</span> <span class="n">curr</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;&amp;</span> <span class="n">visited</span><span class="p">);</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="k">while</span> <span class="p">(</span><span class="n">solve</span><span class="p">());</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="kt">bool</span> <span class="n">solve</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">ll</span> <span class="n">N</span><span class="p">,</span> <span class="n">M</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">N</span> <span class="o">&gt;&gt;</span> <span class="n">M</span><span class="p">;</span> <span class="k">if</span> <span class="p">(</span><span class="n">N</span> <span class="o">==</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">M</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nb">false</span><span class="p">;</span> <span class="p">}</span> <span class="n">ll</span> <span class="n">S</span><span class="p">,</span> <span class="n">D</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">S</span> <span class="o">&gt;&gt;</span> <span class="n">D</span><span class="p">;</span> <span class="n">Graph</span> <span class="n">graph</span><span class="p">,</span> <span class="n">reversed_graph</span><span class="p">;</span> <span class="k">while</span> <span class="p">(</span><span class="n">M</span><span class="o">--</span><span class="p">)</span> <span class="p">{</span> <span class="n">ll</span> <span class="n">U</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">P</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">U</span> <span class="o">&gt;&gt;</span> <span class="n">V</span> <span class="o">&gt;&gt;</span> <span class="n">P</span><span class="p">;</span> <span class="n">graph</span><span class="p">[</span><span class="n">U</span><span class="p">][</span><span class="n">V</span><span class="p">]</span> <span class="o">=</span> <span class="n">P</span><span class="p">;</span> <span class="n">reversed_graph</span><span class="p">[</span><span class="n">V</span><span class="p">][</span><span class="n">U</span><span class="p">]</span> <span class="o">=</span> <span class="n">P</span><span class="p">;</span> <span class="p">}</span> <span class="k">auto</span> <span class="n">result</span> <span class="o">=</span> <span class="n">shortest_path</span><span class="o">::</span><span class="n">dijkstra</span><span class="o">::</span><span class="n">getShortestPath</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span> <span class="n">S</span><span class="p">);</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;</span> <span class="n">visited</span><span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="nb">false</span><span class="p">);</span> <span class="n">RemoveShortestPaths</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span> <span class="n">reversed_graph</span><span class="p">,</span> <span class="n">result</span><span class="p">,</span> <span class="n">D</span><span class="p">,</span> <span class="n">visited</span><span class="p">);</span> <span class="n">result</span> <span class="o">=</span> <span class="n">shortest_path</span><span class="o">::</span><span class="n">dijkstra</span><span class="o">::</span><span class="n">getShortestPath</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span> <span class="n">S</span><span class="p">);</span> <span class="k">if</span> <span class="p">(</span><span class="n">result</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">D</span><span class="p">)</span> <span class="o">==</span> <span class="n">result</span><span class="p">.</span><span class="n">end</span><span class="p">())</span> <span class="p">{</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="o">-</span><span class="mi">1</span> <span class="o">&lt;&lt;</span> <span class="sc">'\n'</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">result</span><span class="p">[</span><span class="n">D</span><span class="p">]</span> <span class="o">&lt;&lt;</span> <span class="sc">'\n'</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="nb">true</span><span class="p">;</span> <span class="p">}</span> <span class="kt">void</span> <span class="n">RemoveShortestPaths</span><span class="p">(</span><span class="n">Graph</span><span class="o">&amp;</span> <span class="n">graph</span><span class="p">,</span> <span class="n">Graph</span><span class="o">&amp;</span> <span class="n">reversed_graph</span><span class="p">,</span> <span class="n">gp_hash_table</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;&amp;</span> <span class="n">dist</span><span class="p">,</span> <span class="n">ll</span> <span class="n">curr</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;&amp;</span> <span class="n">visited</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">visited</span><span class="p">[</span><span class="n">curr</span><span class="p">])</span> <span class="k">return</span><span class="p">;</span> <span class="n">visited</span><span class="p">[</span><span class="n">curr</span><span class="p">]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="k">auto</span><span class="o">&amp;</span> <span class="p">[</span><span class="n">prev</span><span class="p">,</span> <span class="n">weight</span><span class="p">]</span> <span class="o">:</span> <span class="n">reversed_graph</span><span class="p">[</span><span class="n">curr</span><span class="p">])</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">dist</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">prev</span><span class="p">)</span> <span class="o">!=</span> <span class="n">dist</span><span class="p">.</span><span class="n">end</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="n">dist</span><span class="p">[</span><span class="n">prev</span><span class="p">]</span> <span class="o">+</span> <span class="n">weight</span> <span class="o">==</span> <span class="n">dist</span><span class="p">[</span><span class="n">curr</span><span class="p">])</span> <span class="p">{</span> <span class="n">graph</span><span class="p">[</span><span class="n">prev</span><span class="p">].</span><span class="n">erase</span><span class="p">(</span><span class="n">curr</span><span class="p">);</span> <span class="n">RemoveShortestPaths</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span> <span class="n">reversed_graph</span><span class="p">,</span> <span class="n">dist</span><span class="p">,</span> <span class="n">prev</span><span class="p">,</span> <span class="n">visited</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>실행 결과 ‘틀렸습니다’ 가 떴다.</p> <h3 id="5번째-시도">5번째 시도</h3> <p>알고리즘에는 분명 문제가 없다고 생각해서 내부 동작을 뜯어봤는데, 어떤 간선들을 확인하지 않는다는 것을 알 수 있었다. 혹시나 해서 <code class="language-plaintext highlighter-rouge">__gnu_pbds::gp_hash_table</code> 대신 <code class="language-plaintext highlighter-rouge">std::vector</code> 를 이용하여 그래프를 다루도록 해보았다.</p> <p>코드는 <code class="language-plaintext highlighter-rouge">main.cpp</code> 파일만 다음과 같이 수정하였다.</p> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;bits/extc++.h&gt;</span><span class="cp"> #include</span> <span class="cpf">"custom_algorithms.hpp"</span><span class="cp"> </span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">__gnu_pbds</span><span class="p">;</span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">custom_algorithms</span><span class="p">;</span> <span class="k">using</span> <span class="n">ll</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">ull</span> <span class="o">=</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">ld</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">double</span><span class="p">;</span> <span class="k">using</span> <span class="n">pll</span> <span class="o">=</span> <span class="n">pair</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;</span><span class="p">;</span> <span class="k">using</span> <span class="n">Graph</span> <span class="o">=</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">pll</span><span class="o">&gt;&gt;</span><span class="p">;</span> <span class="kt">bool</span> <span class="nf">solve</span><span class="p">(</span><span class="kt">void</span><span class="p">);</span> <span class="kt">void</span> <span class="nf">RemoveShortestPaths</span><span class="p">(</span><span class="n">Graph</span><span class="o">&amp;</span> <span class="n">graph</span><span class="p">,</span> <span class="k">const</span> <span class="n">Graph</span><span class="o">&amp;</span> <span class="n">reversed_graph</span><span class="p">,</span> <span class="k">const</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;&amp;</span> <span class="n">dist</span><span class="p">,</span> <span class="n">ll</span> <span class="n">curr</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;&amp;</span> <span class="n">visited</span><span class="p">);</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="k">while</span> <span class="p">(</span><span class="n">solve</span><span class="p">());</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="kt">bool</span> <span class="n">solve</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">ll</span> <span class="n">N</span><span class="p">,</span> <span class="n">M</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">N</span> <span class="o">&gt;&gt;</span> <span class="n">M</span><span class="p">;</span> <span class="k">if</span> <span class="p">(</span><span class="n">N</span> <span class="o">==</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">M</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nb">false</span><span class="p">;</span> <span class="p">}</span> <span class="n">ll</span> <span class="n">S</span><span class="p">,</span> <span class="n">D</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">S</span> <span class="o">&gt;&gt;</span> <span class="n">D</span><span class="p">;</span> <span class="n">Graph</span> <span class="n">graph</span><span class="p">(</span><span class="n">N</span><span class="p">),</span> <span class="n">reversed_graph</span><span class="p">(</span><span class="n">N</span><span class="p">);</span> <span class="k">while</span> <span class="p">(</span><span class="n">M</span><span class="o">--</span><span class="p">)</span> <span class="p">{</span> <span class="n">ll</span> <span class="n">U</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">P</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">U</span> <span class="o">&gt;&gt;</span> <span class="n">V</span> <span class="o">&gt;&gt;</span> <span class="n">P</span><span class="p">;</span> <span class="n">graph</span><span class="p">[</span><span class="n">U</span><span class="p">].</span><span class="n">emplace_back</span><span class="p">(</span><span class="n">make_pair</span><span class="p">(</span><span class="n">V</span><span class="p">,</span> <span class="n">P</span><span class="p">));</span> <span class="n">reversed_graph</span><span class="p">[</span><span class="n">V</span><span class="p">].</span><span class="n">emplace_back</span><span class="p">(</span><span class="n">make_pair</span><span class="p">(</span><span class="n">U</span><span class="p">,</span> <span class="n">P</span><span class="p">));</span> <span class="p">}</span> <span class="k">auto</span> <span class="n">result</span> <span class="o">=</span> <span class="n">shortest_path</span><span class="o">::</span><span class="n">dijkstra</span><span class="o">::</span><span class="n">GetShortestPath</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span> <span class="n">S</span><span class="p">);</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;</span> <span class="n">visited</span><span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="nb">false</span><span class="p">);</span> <span class="n">RemoveShortestPaths</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span> <span class="n">reversed_graph</span><span class="p">,</span> <span class="n">result</span><span class="p">,</span> <span class="n">D</span><span class="p">,</span> <span class="n">visited</span><span class="p">);</span> <span class="n">result</span> <span class="o">=</span> <span class="n">shortest_path</span><span class="o">::</span><span class="n">dijkstra</span><span class="o">::</span><span class="n">GetShortestPath</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span> <span class="n">S</span><span class="p">);</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">result</span><span class="p">[</span><span class="n">D</span><span class="p">]</span> <span class="o">&lt;&lt;</span> <span class="sc">'\n'</span><span class="p">;</span> <span class="k">return</span> <span class="nb">true</span><span class="p">;</span> <span class="p">}</span> <span class="kt">void</span> <span class="n">RemoveShortestPaths</span><span class="p">(</span><span class="n">Graph</span><span class="o">&amp;</span> <span class="n">graph</span><span class="p">,</span> <span class="k">const</span> <span class="n">Graph</span><span class="o">&amp;</span> <span class="n">reversed_graph</span><span class="p">,</span> <span class="k">const</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;&amp;</span> <span class="n">dist</span><span class="p">,</span> <span class="n">ll</span> <span class="n">curr</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;&amp;</span> <span class="n">visited</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">visited</span><span class="p">[</span><span class="n">curr</span><span class="p">])</span> <span class="k">return</span><span class="p">;</span> <span class="n">visited</span><span class="p">[</span><span class="n">curr</span><span class="p">]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="p">[</span><span class="n">prev</span><span class="p">,</span> <span class="n">weight</span><span class="p">]</span> <span class="o">:</span> <span class="n">reversed_graph</span><span class="p">[</span><span class="n">curr</span><span class="p">])</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">dist</span><span class="p">[</span><span class="n">prev</span><span class="p">]</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span> <span class="o">&amp;&amp;</span> <span class="n">dist</span><span class="p">[</span><span class="n">prev</span><span class="p">]</span> <span class="o">+</span> <span class="n">weight</span> <span class="o">==</span> <span class="n">dist</span><span class="p">[</span><span class="n">curr</span><span class="p">])</span> <span class="p">{</span> <span class="n">graph</span><span class="p">[</span><span class="n">prev</span><span class="p">].</span><span class="n">erase</span><span class="p">(</span><span class="n">remove</span><span class="p">(</span><span class="n">graph</span><span class="p">[</span><span class="n">prev</span><span class="p">].</span><span class="n">begin</span><span class="p">(),</span> <span class="n">graph</span><span class="p">[</span><span class="n">prev</span><span class="p">].</span><span class="n">end</span><span class="p">(),</span> <span class="n">make_pair</span><span class="p">(</span><span class="n">curr</span><span class="p">,</span> <span class="n">weight</span><span class="p">)),</span> <span class="n">graph</span><span class="p">[</span><span class="n">prev</span><span class="p">].</span><span class="n">end</span><span class="p">());</span> <span class="n">RemoveShortestPaths</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span> <span class="n">reversed_graph</span><span class="p">,</span> <span class="n">dist</span><span class="p">,</span> <span class="n">prev</span><span class="p">,</span> <span class="n">visited</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>그러자 모든 테스트 케이스를 통과하고 ‘맞았습니다’가 나오는 것을 확인할 수 있었다.</p> <h2 id="마무리">마무리</h2> <p>일단 풀긴 풀었는데 뭔가 기분이 찜찜하다. 내 생각대로라면 <code class="language-plaintext highlighter-rouge">__gnu_pbds::gp_hash_table</code> 을 쓰나 <code class="language-plaintext highlighter-rouge">std::vector</code> 를 쓰나 결과에는 차이가 없어야 하는데, 어째서 한쪽은 제대로 작동하지 않고 나머지 한쪽만 제대로 작동하는지 모르겠다…</p> <p>지금은 이 문제를 푸는데만 해도 상당한 시간과 정신력을 소모했기 때문에 지금은 이 문제를 더 깊이 파고들지 않으려고 한다. 앞으로 비슷한 상황이 나오면 그 때 좀 더 자세히 알아봐야겠다.</p> <p>내가 작성한 <code class="language-plaintext highlighter-rouge">custom_algorithms.hpp</code> 파일은 내 깃헙 레포지토리<sup><a href="#footnote_2">2</a></sup>에서 확인할 수 있다.</p> <p>오늘의 PS는 여기까지!</p> <hr /> <p><a name="footnote_1">1</a>: <a href="https://www.acmicpc.net/problem/5719">https://www.acmicpc.net/problem/5719</a><br /> <a name="footnote_2">2</a>: <a href="https://github.com/ChoiCube84/baekjoon-solutions/blob/main/C%2B%2B/5719/custom_algorithms.hpp">https://github.com/ChoiCube84/baekjoon-solutions/blob/main/C%2B%2B/5719/custom_algorithms.hpp</a></p> Sun, 15 Sep 2024 23:59:00 +0900 https://choicube84.github.io/study/2024/09/15/baekjoon_5719.html https://choicube84.github.io/study/2024/09/15/baekjoon_5719.html problem_solving Study 백준 13334번 <h1 id="백준-13334번">백준 13334번</h1> <p>오늘 풀어본 문제는 백준의 13334번 문제<sup><a href="#footnote_1">1</a></sup>이다. 문제 풀이에 사용한 언어는 C++ 이다.</p> <h2 id="solvedac-기준-class">solved.ac 기준 CLASS</h2> <p><img src="https://static.solved.ac/class/c6.svg" width="50%" height="50%" alt="CLASS 6" /></p> <h2 id="문제-정보">문제 정보</h2> <p>이 문제의 내용과 조건은 다음과 같다.</p> <h3 id="문제">문제</h3> <p>집과 사무실을 통근하는 $n$ 명의 사람들이 있다. 각 사람의 집과 사무실은 수평선 상에 있는 서로 다른 점에 위치하고 있다. 임의의 두 사람 $A$, $B$ 에 대하여, $A$ 의 집 혹은 사무실의 위치가 $B$ 의 집 혹은 사무실의 위치와 같을 수 있다. 통근을 하는 사람들의 편의를 위하여 일직선 상의 어떤 두 점을 잇는 철로를 건설하여, 기차를 운행하려고 한다. 제한된 예산 때문에, 철로의 길이는 $d$ 로 정해져 있다. 집과 사무실의 위치 모두 철로 선분에 포함되는 사람들의 수가 최대가 되도록, 철로 선분을 정하고자 한다.</p> <p>양의 정수 $d$ 와 $n$ 개의 정수쌍, $(h_i,\ o_i)$, $1 \le i \le n$,이 주어져 있다. 여기서 $h_i$ 와 $o_i$ 는 사람 $i$ 의 집과 사무실의 위치이다. 길이 $d$ 의 모든 선분 $L$ 에 대하여, 집과 사무실의 위치가 모두 $L$ 에 포함되는 사람들의 최대 수를 구하는 프로그램을 작성하시오.</p> <p><img src="https://onlinejudgeimages.s3-ap-northeast-1.amazonaws.com/problem/13334/1.png" width="50%" height="50%" alt="그림 1" /></p> <center>그림 1. 8 명의 집과 사무실의 위치</center> <p>그림 1 에 있는 예를 고려해보자. 여기서 $n = 8$, $(h_1,\ o_1) = (5,\ 40)$, $(h_2,\ o_2) = (35,\ 25)$, $(h_3,\ o_3) = (10,\ 20)$, $(h_4,\ o_4) = (10,\ 25)$, $(h_5,\ o_5) = (30,\ 50)$, $(h_6,\ o_6) = (50,\ 60)$, $(h_7,\ o_7) = (30,\ 25)$, $(h_8,\ o_8) = (80,\ 100)$ 이고, $d = 30$ 이다. 이 예에서, 위치 $10$ 과 $40$ 사이의 빨간색 선분 $L$ 이, 가장 많은 사람들에 대하여 집과 사무실 위치 모두 포함되는 선분 중 하나이다. 따라서 답은 $4$ 이다.</p> <h3 id="입력">입력</h3> <p>입력은 표준입력을 사용한다. 첫 번째 줄에 사람 수를 나타내는 양의 정수 $n$ $(1 \le n \le 100,000)$ 이 주어진다. 다음 $n$ 개의 각 줄에 정수 쌍 $(h_i,\ o_i)$ 가 주어진다. 여기서 $h_i$ 와 $o_i$ 는 $−100,000,000$ 이상, $100,000,000$ 이하의 서로 다른 정수이다. 마지막 줄에, 철로의 길이를 나타내는 정수 $d$ $(1 \le d \le 200,000,000)$ 가 주어진다.</p> <h3 id="출력">출력</h3> <p>출력은 표준출력을 사용한다. 길이 $d$ 의 임의의 선분에 대하여, 집과 사무실 위치가 모두 그 선분에 포함되는 사람들의 최대 수를 한 줄에 출력한다.</p> <h2 id="풀이과정">풀이과정</h2> <h3 id="1번째-시도">1번째 시도</h3> <p>문제를 해결하기 위해 사용한 방식은 다음과 같다.</p> <ol> <li> <p>각 구간들을 입력받고, 왼쪽 위치를 기준으로 정렬되도록 우선순위 큐에 넣는다.</p> </li> <li> <p>우선순위 큐에서 구간을 하나씩 꺼낸 뒤, 맨 앞에 있는 구간의 왼쪽 위치를 철로의 왼쪽 위치로 두었을 때 꺼낸 구간이 포함되면 계속해서 큐에 넣고, 포함되지 않을 때 현재 큐의 크기를 이용하여 최댓값을 갱신하고 큐의 맨 앞 원소를 제거한다.</p> </li> <li> <p>우선순위 큐에서 모든 구간이 꺼내질 때까지 2를 반복한다.</p> </li> </ol> <p>코드는 다음과 같이 작성하였다.</p> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;bits/extc++.h&gt;</span><span class="cp"> </span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">__gnu_pbds</span><span class="p">;</span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">using</span> <span class="n">ll</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">ull</span> <span class="o">=</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">pll</span> <span class="o">=</span> <span class="n">pair</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;</span><span class="p">;</span> <span class="k">using</span> <span class="n">ld</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">double</span><span class="p">;</span> <span class="k">struct</span> <span class="nc">cmp</span> <span class="p">{</span> <span class="kt">bool</span> <span class="k">operator</span><span class="p">()(</span><span class="k">const</span> <span class="n">pll</span><span class="o">&amp;</span> <span class="n">a</span><span class="p">,</span> <span class="k">const</span> <span class="n">pll</span><span class="o">&amp;</span> <span class="n">b</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">a</span><span class="p">.</span><span class="n">first</span> <span class="o">==</span> <span class="n">b</span><span class="p">.</span><span class="n">first</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="n">a</span><span class="p">.</span><span class="n">second</span> <span class="o">&gt;</span> <span class="n">b</span><span class="p">.</span><span class="n">second</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="n">a</span><span class="p">.</span><span class="n">first</span> <span class="o">&gt;</span> <span class="n">b</span><span class="p">.</span><span class="n">first</span><span class="p">;</span> <span class="p">}</span> <span class="p">};</span> <span class="kt">int</span> <span class="n">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="n">ll</span> <span class="n">n</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">n</span><span class="p">;</span> <span class="n">std</span><span class="o">::</span><span class="n">priority_queue</span><span class="o">&lt;</span><span class="n">pll</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">pll</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">cmp</span><span class="o">&gt;</span> <span class="n">pq</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">ll</span> <span class="n">h</span><span class="p">,</span> <span class="n">o</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">h</span> <span class="o">&gt;&gt;</span> <span class="n">o</span><span class="p">;</span> <span class="k">if</span> <span class="p">(</span><span class="n">h</span> <span class="o">&gt;</span> <span class="n">o</span><span class="p">)</span> <span class="p">{</span> <span class="n">swap</span><span class="p">(</span><span class="n">h</span><span class="p">,</span> <span class="n">o</span><span class="p">);</span> <span class="p">}</span> <span class="n">pq</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">make_pair</span><span class="p">(</span><span class="n">h</span><span class="p">,</span> <span class="n">o</span><span class="p">));</span> <span class="p">}</span> <span class="n">ll</span> <span class="n">d</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">d</span><span class="p">;</span> <span class="n">ll</span> <span class="n">maximum</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">queue</span><span class="o">&lt;</span><span class="n">pll</span><span class="o">&gt;</span> <span class="n">q</span><span class="p">;</span> <span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">pq</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span> <span class="p">{</span> <span class="k">auto</span> <span class="n">curr</span> <span class="o">=</span> <span class="n">pq</span><span class="p">.</span><span class="n">top</span><span class="p">();</span> <span class="n">pq</span><span class="p">.</span><span class="n">pop</span><span class="p">();</span> <span class="k">if</span> <span class="p">(</span><span class="n">q</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">curr</span><span class="p">.</span><span class="n">second</span> <span class="o">&gt;</span> <span class="n">curr</span><span class="p">.</span><span class="n">first</span> <span class="o">+</span> <span class="n">d</span><span class="p">)</span> <span class="p">{</span> <span class="k">continue</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">q</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">curr</span><span class="p">);</span> <span class="n">maximum</span> <span class="o">=</span> <span class="n">max</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;</span><span class="p">(</span><span class="n">maximum</span><span class="p">,</span> <span class="n">q</span><span class="p">.</span><span class="n">size</span><span class="p">());</span> <span class="p">}</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">q</span><span class="p">.</span><span class="n">empty</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="n">curr</span><span class="p">.</span><span class="n">second</span> <span class="o">&gt;</span> <span class="n">q</span><span class="p">.</span><span class="n">front</span><span class="p">().</span><span class="n">first</span> <span class="o">+</span> <span class="n">d</span><span class="p">)</span> <span class="p">{</span> <span class="n">q</span><span class="p">.</span><span class="n">pop</span><span class="p">();</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">q</span><span class="p">.</span><span class="n">empty</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="n">curr</span><span class="p">.</span><span class="n">second</span> <span class="o">&gt;</span> <span class="n">curr</span><span class="p">.</span><span class="n">first</span> <span class="o">+</span> <span class="n">d</span><span class="p">)</span> <span class="p">{</span> <span class="k">continue</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">q</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">curr</span><span class="p">);</span> <span class="n">maximum</span> <span class="o">=</span> <span class="n">max</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;</span><span class="p">(</span><span class="n">maximum</span><span class="p">,</span> <span class="n">q</span><span class="p">.</span><span class="n">size</span><span class="p">());</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">maximum</span><span class="p">;</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> </code></pre></div></div> <p>실행 결과 ‘틀렸습니다’ 가 떴다.</p> <h3 id="2번째-시도">2번째 시도</h3> <p>처음 접근의 잘못되었던 부분은, 구간의 ‘왼쪽’ 위치가 아닌, ‘오른쪽’ 위치로 정렬을 실시해야 한다는 점이었다. 오른쪽 위치를 기준으로 정렬한 뒤, 왼쪽 위치들을 일반 큐가 아닌 우선순위 큐로 저장하게 하여 해결을 시도하였다.</p> <p>코드는 다음과 같이 수정하였다.</p> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;bits/extc++.h&gt;</span><span class="cp"> </span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">__gnu_pbds</span><span class="p">;</span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">using</span> <span class="n">ll</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">ull</span> <span class="o">=</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">pll</span> <span class="o">=</span> <span class="n">pair</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;</span><span class="p">;</span> <span class="k">using</span> <span class="n">ld</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">double</span><span class="p">;</span> <span class="k">struct</span> <span class="nc">cmp</span> <span class="p">{</span> <span class="kt">bool</span> <span class="k">operator</span><span class="p">()(</span><span class="k">const</span> <span class="n">pll</span><span class="o">&amp;</span> <span class="n">a</span><span class="p">,</span> <span class="k">const</span> <span class="n">pll</span><span class="o">&amp;</span> <span class="n">b</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">a</span><span class="p">.</span><span class="n">second</span> <span class="o">==</span> <span class="n">b</span><span class="p">.</span><span class="n">second</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="n">a</span><span class="p">.</span><span class="n">first</span> <span class="o">&lt;</span> <span class="n">b</span><span class="p">.</span><span class="n">first</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="n">a</span><span class="p">.</span><span class="n">second</span> <span class="o">&lt;</span> <span class="n">b</span><span class="p">.</span><span class="n">second</span><span class="p">;</span> <span class="p">}</span> <span class="p">};</span> <span class="kt">int</span> <span class="n">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="n">ll</span> <span class="n">n</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">n</span><span class="p">;</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">pll</span><span class="o">&gt;</span> <span class="n">lines</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">ll</span> <span class="n">h</span><span class="p">,</span> <span class="n">o</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">h</span> <span class="o">&gt;&gt;</span> <span class="n">o</span><span class="p">;</span> <span class="k">if</span> <span class="p">(</span><span class="n">h</span> <span class="o">&gt;</span> <span class="n">o</span><span class="p">)</span> <span class="p">{</span> <span class="n">swap</span><span class="p">(</span><span class="n">h</span><span class="p">,</span> <span class="n">o</span><span class="p">);</span> <span class="p">}</span> <span class="n">lines</span><span class="p">.</span><span class="n">emplace_back</span><span class="p">(</span><span class="n">make_pair</span><span class="p">(</span><span class="n">h</span><span class="p">,</span> <span class="n">o</span><span class="p">));</span> <span class="p">}</span> <span class="n">sort</span><span class="p">(</span><span class="n">lines</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">lines</span><span class="p">.</span><span class="n">end</span><span class="p">(),</span> <span class="n">cmp</span><span class="p">());</span> <span class="n">ll</span> <span class="n">d</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">d</span><span class="p">;</span> <span class="n">ll</span> <span class="n">maximum</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">std</span><span class="o">::</span><span class="n">priority_queue</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">greater</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&gt;</span> <span class="n">pq</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">auto</span> <span class="n">curr</span> <span class="o">=</span> <span class="n">lines</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="k">if</span> <span class="p">(</span><span class="n">curr</span><span class="p">.</span><span class="n">second</span> <span class="o">-</span> <span class="n">curr</span><span class="p">.</span><span class="n">first</span> <span class="o">&lt;=</span> <span class="n">d</span><span class="p">)</span> <span class="p">{</span> <span class="n">pq</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">curr</span><span class="p">.</span><span class="n">first</span><span class="p">);</span> <span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">pq</span><span class="p">.</span><span class="n">empty</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="n">curr</span><span class="p">.</span><span class="n">second</span> <span class="o">&gt;</span> <span class="n">pq</span><span class="p">.</span><span class="n">top</span><span class="p">()</span> <span class="o">+</span> <span class="n">d</span><span class="p">)</span> <span class="p">{</span> <span class="n">pq</span><span class="p">.</span><span class="n">pop</span><span class="p">();</span> <span class="p">}</span> <span class="n">maximum</span> <span class="o">=</span> <span class="n">max</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;</span><span class="p">(</span><span class="n">maximum</span><span class="p">,</span> <span class="n">pq</span><span class="p">.</span><span class="n">size</span><span class="p">());</span> <span class="p">}</span> <span class="p">}</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">maximum</span><span class="p">;</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> </code></pre></div></div> <p>그러자 모든 테스트 케이스를 통과하고 ‘맞았습니다’가 나오는 것을 확인할 수 있었다.</p> <h2 id="마무리">마무리</h2> <p>이 문제를 풀면서 스위핑 알고리즘이라는 것을 알게 되었다. 데이터들을 한 번씩 스캔해나가며 푸는 알고리즘들을 스위핑 알고리즘이라고 부르는데, 앞으로 가끔 보게 될 것 같은 기분이 든다.</p> <p>오늘의 PS는 여기까지!</p> <hr /> <p><a name="footnote_1">1</a>: <a href="https://www.acmicpc.net/problem/13334">https://www.acmicpc.net/problem/13334</a></p> Sun, 08 Sep 2024 23:59:00 +0900 https://choicube84.github.io/study/2024/09/08/baekjoon_13334.html https://choicube84.github.io/study/2024/09/08/baekjoon_13334.html problem_solving Study 백준 2533번 <h1 id="백준-2533번">백준 2533번</h1> <p>오늘 풀어본 문제는 백준의 2533번 문제<sup><a href="#footnote_1">1</a></sup>이다. 문제 풀이에 사용한 언어는 C++ 이다.</p> <h2 id="solvedac-기준-class">solved.ac 기준 CLASS</h2> <p><img src="https://static.solved.ac/class/c6.svg" width="50%" height="50%" alt="CLASS 6" /></p> <h2 id="문제-정보">문제 정보</h2> <p>이 문제의 내용과 조건은 다음과 같다.</p> <h3 id="문제">문제</h3> <p>페이스북, 트위터, 카카오톡과 같은 사회망 서비스(SNS)가 널리 사용됨에 따라, 사회망을 통하여 사람들이 어떻게 새로운 아이디어를 받아들이게 되는가를 이해하는 문제가 중요해졌다. 사회망에서 사람들의 친구 관계는 그래프로 표현할 수 있는데, 이 그래프에서 사람은 정점으로 표현되고, 두 정점을 잇는 에지는 두 정점으로 표현되는 두 사람이 서로 친구 관계임을 표현한다.</p> <p>예를 들어, 철수와 영희, 철수와 만수, 영희와 순희가 서로 친구 관계라면 이를 표현하는 친구 관계 그래프는 다음과 같다.</p> <p><img src="https://upload.acmicpc.net/c0d162b4-20d6-46eb-be8f-d06ae8bf1e9c/-/preview/" width="50%" height="50%" alt="figure 1" /></p> <p>친구 관계 그래프를 이용하면 사회망 서비스에서 어떤 새로운 아이디어가 전파되는 과정을 이해하는데 도움을 줄 수 있다. 어떤 새로운 아이디어를 먼저 받아들인 사람을 얼리 아답터(early adaptor)라고 하는데, 사회망 서비스에 속한 사람들은 얼리 아답터이거나 얼리 아답터가 아니다. 얼리 아답터가 아닌 사람들은 자신의 모든 친구들이 얼리 아답터일 때만 이 아이디어를 받아들인다.</p> <p>어떤 아이디어를 사회망 서비스에서 퍼뜨리고자 할 때, 가능한 한 최소의 수의 얼리 아답터를 확보하여 모든 사람이 이 아이디어를 받아들이게 하는 문제는 매우 중요하다.</p> <p>일반적인 그래프에서 이 문제를 푸는 것이 매우 어렵다는 것이 알려져 있기 때문에, 친구 관계 그래프가 트리인 경우, 즉 모든 두 정점 사이에 이들을 잇는 경로가 존재하면서 사이클이 존재하지 않는 경우만 고려한다.</p> <p>예를 들어, $8$ 명의 사람으로 이루어진 다음 친구 관계 트리를 생각해보자. $2$, $3$, $4$ 번 노드가 표현하는 사람들이 얼리 아답터라면, 얼리 아답터가 아닌 사람들은 자신의 모든 친구가 얼리 아답터이기 때문에 새로운 아이디어를 받아들인다.</p> <p><img src="https://upload.acmicpc.net/ac2e6a89-2e66-4cab-8f07-951372ef7fcc/-/preview/" width="50%" height="50%" alt="figure 2" /></p> <p>친구 관계 트리가 주어졌을 때, 모든 개인이 새로운 아이디어를 수용하기 위하여 필요한 최소 얼리 어답터의 수를 구하는 프로그램을 작성하시오.</p> <h3 id="입력">입력</h3> <p>첫 번째 줄에는 친구 관계 트리의 정점 개수 $N$ 이 주어진다. 단, $2 \le N \le 1,000,000$ 이며, 각 정점은 $1$ 부터 $N$ 까지 일련번호로 표현된다. 두 번째 줄부터 $N-1$ 개의 줄에는 각 줄마다 친구 관계 트리의 에지 $(u, v)$ 를 나타내는 두 정수 $u$ 와 $v$ 가 하나의 빈칸을 사이에 두고 주어진다.</p> <h3 id="출력">출력</h3> <p>주어진 친구 관계 그래프에서 아이디어를 전파하는데 필요한 얼리 아답터의 최소 수를 하나의 정수로 출력한다.</p> <h2 id="풀이과정">풀이과정</h2> <h3 id="1번째-시도">1번째 시도</h3> <p>이 문제를 해결하기 위해 사용한 방법은 DP인데, 트리에서 DP를 해야한다는 점이 독특했다.</p> <p>우선 내가 떠올린 방법은 루트 노드부터 시작하여 현재 노드가 얼리 어답터가 아닌 경우, 자식 노드들이 모두 얼리 어답터인 경우에 해당 자식 노드들을 루트 노드로 하는 서브 트리에서 필요한 얼리 어답터의 수를 모두 더한 값을 현재 노드를 루트 노드로 하는 서브 트리에 필요한 얼리 어답터의 수로 정하고, 현재 노드가 얼리 어답터인 경우 자식 노드들이 얼리 어답터이거나 아닌 경우 중 더 필요한 얼리 어답터의 수가 적은 것들의 합에 1을 더한 것으로 현재 노드를 루트 노드로 하는 서브 트리에 필요한 얼리 어답터의 수로 정하는 것이었다.</p> <p>코드는 다음과 같이 작성하였다.</p> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;bits/extc++.h&gt;</span><span class="cp"> </span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">__gnu_pbds</span><span class="p">;</span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">using</span> <span class="n">ll</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">ull</span> <span class="o">=</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">ld</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">double</span><span class="p">;</span> <span class="k">using</span> <span class="n">pll</span> <span class="o">=</span> <span class="n">pair</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;</span><span class="p">;</span> <span class="kt">void</span> <span class="nf">updateByDFS</span><span class="p">(</span><span class="k">const</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;&gt;&amp;</span> <span class="n">graph</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;&gt;&amp;</span> <span class="n">dp</span><span class="p">,</span> <span class="n">ll</span> <span class="n">curr</span><span class="p">,</span> <span class="n">ll</span> <span class="n">parent</span><span class="p">);</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="n">ll</span> <span class="n">N</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">N</span><span class="p">;</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;&gt;</span> <span class="n">graph</span><span class="p">(</span><span class="n">N</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">N</span><span class="o">-</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">ll</span> <span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">u</span> <span class="o">&gt;&gt;</span> <span class="n">v</span><span class="p">;</span> <span class="n">graph</span><span class="p">[</span><span class="n">u</span><span class="p">].</span><span class="n">push_back</span><span class="p">(</span><span class="n">v</span><span class="p">);</span> <span class="n">graph</span><span class="p">[</span><span class="n">v</span><span class="p">].</span><span class="n">push_back</span><span class="p">(</span><span class="n">u</span><span class="p">);</span> <span class="p">}</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;&gt;</span> <span class="n">dp</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;</span><span class="p">(</span><span class="n">N</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">));</span> <span class="n">updateByDFS</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span> <span class="n">dp</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">min</span><span class="p">(</span><span class="n">dp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">],</span> <span class="n">dp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">1</span><span class="p">]);</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="kt">void</span> <span class="n">updateByDFS</span><span class="p">(</span><span class="k">const</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;&gt;&amp;</span> <span class="n">graph</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;&gt;&amp;</span> <span class="n">dp</span><span class="p">,</span> <span class="n">ll</span> <span class="n">curr</span><span class="p">,</span> <span class="n">ll</span> <span class="n">parent</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">graph</span><span class="p">[</span><span class="n">curr</span><span class="p">].</span><span class="n">size</span><span class="p">()</span> <span class="o">==</span> <span class="mi">1</span> <span class="o">&amp;&amp;</span> <span class="n">parent</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="n">dp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="n">curr</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">dp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="n">curr</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="k">return</span> <span class="p">;</span> <span class="p">}</span> <span class="k">for</span> <span class="p">(</span><span class="k">auto</span><span class="o">&amp;</span> <span class="n">next</span> <span class="o">:</span> <span class="n">graph</span><span class="p">[</span><span class="n">curr</span><span class="p">])</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">next</span> <span class="o">==</span> <span class="n">parent</span><span class="p">)</span> <span class="p">{</span> <span class="k">continue</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">updateByDFS</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span> <span class="n">dp</span><span class="p">,</span> <span class="n">next</span><span class="p">,</span> <span class="n">curr</span><span class="p">);</span> <span class="n">dp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="n">curr</span><span class="p">]</span> <span class="o">+=</span> <span class="n">dp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="n">next</span><span class="p">];</span> <span class="n">dp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="n">curr</span><span class="p">]</span> <span class="o">+=</span> <span class="n">min</span><span class="p">(</span><span class="n">dp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="n">next</span><span class="p">],</span> <span class="n">dp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="n">next</span><span class="p">]);</span> <span class="p">}</span> <span class="p">}</span> <span class="n">dp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="n">curr</span><span class="p">]</span><span class="o">++</span><span class="p">;</span> <span class="p">}</span> </code></pre></div></div> <p>그러자 모든 테스트 케이스를 통과하고 ‘맞았습니다’가 나오는 것을 확인할 수 있었다.</p> <h2 id="마무리">마무리</h2> <p>DP 문제는 지겹게 풀어봤지만, 트리에서 DP 문제를 풀어본건 처음인 것 같다! 점화식을 떠올리는 것도 생각보다 할만했던 재미있는 문제였던 것 같다.</p> <p>오늘의 PS는 여기까지!</p> <hr /> <p><a name="footnote_1">1</a>: <a href="https://www.acmicpc.net/problem/2533">https://www.acmicpc.net/problem/2533</a></p> Sun, 25 Aug 2024 23:59:00 +0900 https://choicube84.github.io/study/2024/08/25/baekjoon_2533.html https://choicube84.github.io/study/2024/08/25/baekjoon_2533.html problem_solving Study 백준 1019번 <h1 id="백준-1019번">백준 1019번</h1> <p>오늘 풀어본 문제는 백준의 1019번 문제<sup><a href="#footnote_1">1</a></sup>이다. 문제 풀이에 사용한 언어는 C++ 이다.</p> <h2 id="solvedac-기준-class">solved.ac 기준 CLASS</h2> <p><img src="https://static.solved.ac/class/c6.svg" width="50%" height="50%" alt="CLASS 6" /></p> <h2 id="문제-정보">문제 정보</h2> <p>이 문제의 내용과 조건은 다음과 같다.</p> <h3 id="문제">문제</h3> <p>지민이는 전체 페이지의 수가 $N$ 인 책이 하나 있다. 첫 페이지는 $1$ 페이지이고, 마지막 페이지는 $N$ 페이지이다. 각 숫자가 전체 페이지 번호에서 모두 몇 번 나오는지 구해보자.</p> <h3 id="입력">입력</h3> <p>첫째 줄에 $N$ 이 주어진다. $N$ 은 $1,000,000,000$ 보다 작거나 같은 자연수이다.</p> <h3 id="출력">출력</h3> <p>첫째 줄에 $0$ 이 총 몇 번 나오는지, $1$ 이 총 몇 번 나오는지, …, $9$ 가 총 몇 번 나오는지를 공백으로 구분해 출력한다.</p> <h2 id="풀이과정">풀이과정</h2> <h3 id="1번째-시도">1번째 시도</h3> <p>수의 범위가 크기 때문에 각 수에서 숫자의 개수를 일일히 세는 방식으로는 해결할 수 없을 것이라고 생각하였다.</p> <p>대신 떠올린 방법은 수의 범위를 분할해나가는 방식으로 전체 숫자의 개수를 세는 것이었다.</p> <p>예를 들어, 페이지의 수가 $723456$ 이라고 하면 다음과 같이 분할과 셈을 한다.</p> <ul> <li> <p>1 ~ 723456</p> <ul> <li>1 ~ 699999</li> </ul> - 1 ~ 99999 <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> - 1 ~ 9999 - 1 ~ 999 - 1 ~ 99 - 1 ~ 9 - 10 ~ 99 - 10 ~ 19 - ... - 90 ~ 99 - 100 ~ 999 - 100 ~ 199 - ... - 900 ~ 999 - 1000 ~ 9999 - 1000 ~ 1999 - ... - 9000 ~ 9999 - 10000 ~ 99999 - 10000 ~ 19999 - ... - 90000 ~ 99999 - 100000 ~ 199999 - 200000 ~ 299999 - 300000 ~ 399999 - 400000 ~ 499999 - 500000 ~ 599999 - 600000 ~ 699999 </code></pre></div> </div> <ul> <li>700000 ~ 723456</li> </ul> - 맨 앞에 오는 7의 개수를 세어줌 <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> - 00000 ~ 23456 - 00000 ~ 19999 - 00000 ~ 09999 - 10000 ~ 19999 - 20000 ~ 23456 - 맨 앞에 오는 2의 개수를 세어줌 - 0000 ~ 3456 - 0000 ~ 2999 - 0000 ~ 0999 - 1000 ~ 1999 - 2000 ~ 2999 - 3000 ~ 3456 - 맨 앞에 오는 3의 개수를 세어줌 - 000 ~ 456 - 000 ~ 399 - 000 ~ 099 - ... - 300 ~ 399 - 400 ~ 456 - 맨 앞에 오는 4의 개수를 세어줌 - 00 ~ 56 - 00 ~ 49 - 00 ~ 09 - ... - 40 ~ 49 - 50 ~ 56 - 맨 앞에 오는 5의 개수를 세어줌 - 0 ~ 6 </code></pre></div> </div> </li> </ul> <p>예제를 보면 특정 구간을 $X00\cdots\ \sim\ X99\cdots$ 와 $(X+1)00\cdots\ \sim\ ABC\cdots$ 형태로 쪼개는 방식을 재귀적으로 진행하여 숫자의 개수를 세어나감을 알 수 있다.</p> <p>코드는 다음과 같이 작성하였다.</p> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;bits/extc++.h&gt;</span><span class="cp"> </span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">__gnu_pbds</span><span class="p">;</span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">using</span> <span class="n">ll</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">ull</span> <span class="o">=</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">ld</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">double</span><span class="p">;</span> <span class="k">using</span> <span class="n">pll</span> <span class="o">=</span> <span class="n">pair</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;</span><span class="p">;</span> <span class="kt">void</span> <span class="nf">update</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">ull</span><span class="o">&gt;&amp;</span> <span class="n">counts</span><span class="p">,</span> <span class="n">ull</span> <span class="n">N</span><span class="p">);</span> <span class="kt">void</span> <span class="nf">zeroPaddedUpdate</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">ull</span><span class="o">&gt;&amp;</span> <span class="n">counts</span><span class="p">,</span> <span class="n">ull</span> <span class="n">N</span><span class="p">,</span> <span class="n">ull</span> <span class="n">digits</span><span class="p">);</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="n">ull</span> <span class="n">N</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">N</span><span class="p">;</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">ull</span><span class="o">&gt;</span> <span class="n">counts</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="n">update</span><span class="p">(</span><span class="n">counts</span><span class="p">,</span> <span class="n">N</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="n">ull</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="mi">10</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">counts</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">&lt;&lt;</span> <span class="sc">' '</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="kt">void</span> <span class="n">update</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">ull</span><span class="o">&gt;&amp;</span> <span class="n">counts</span><span class="p">,</span> <span class="n">ull</span> <span class="n">N</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">N</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">N</span> <span class="o">&lt;</span> <span class="mi">10</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="n">ull</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">N</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">counts</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">++</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">ull</span> <span class="n">digits</span> <span class="o">=</span> <span class="k">static_cast</span><span class="o">&lt;</span><span class="n">ull</span><span class="o">&gt;</span><span class="p">(</span><span class="n">log10l</span><span class="p">(</span><span class="n">N</span><span class="p">));</span> <span class="n">ull</span> <span class="n">powOf10</span> <span class="o">=</span> <span class="k">static_cast</span><span class="o">&lt;</span><span class="n">ull</span><span class="o">&gt;</span><span class="p">(</span><span class="n">powl</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="n">digits</span><span class="p">));</span> <span class="n">ull</span> <span class="n">MSB</span> <span class="o">=</span> <span class="n">N</span> <span class="o">/</span> <span class="n">powOf10</span><span class="p">;</span> <span class="n">update</span><span class="p">(</span><span class="n">counts</span><span class="p">,</span> <span class="n">powOf10</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="n">ull</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">MSB</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">counts</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+=</span> <span class="n">powOf10</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="n">ull</span> <span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="mi">10</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">counts</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">+=</span> <span class="n">powOf10</span> <span class="o">*</span> <span class="n">digits</span> <span class="o">/</span> <span class="mi">10</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="n">counts</span><span class="p">[</span><span class="n">MSB</span><span class="p">]</span> <span class="o">+=</span> <span class="n">N</span> <span class="o">-</span> <span class="p">(</span><span class="n">MSB</span> <span class="o">*</span> <span class="n">powOf10</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="n">zeroPaddedUpdate</span><span class="p">(</span><span class="n">counts</span><span class="p">,</span> <span class="n">N</span> <span class="o">-</span> <span class="p">(</span><span class="n">MSB</span> <span class="o">*</span> <span class="n">powOf10</span><span class="p">),</span> <span class="n">digits</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="kt">void</span> <span class="n">zeroPaddedUpdate</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">ull</span><span class="o">&gt;&amp;</span> <span class="n">counts</span><span class="p">,</span> <span class="n">ull</span> <span class="n">N</span><span class="p">,</span> <span class="n">ull</span> <span class="n">digits</span><span class="p">)</span> <span class="p">{</span> <span class="n">ull</span> <span class="n">currentDigits</span> <span class="o">=</span> <span class="k">static_cast</span><span class="o">&lt;</span><span class="n">ull</span><span class="o">&gt;</span><span class="p">(</span><span class="n">log10l</span><span class="p">(</span><span class="n">N</span><span class="p">));</span> <span class="k">if</span> <span class="p">(</span><span class="n">currentDigits</span> <span class="o">&lt;</span> <span class="n">digits</span><span class="p">)</span> <span class="p">{</span> <span class="n">counts</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+=</span> <span class="p">(</span><span class="n">digits</span> <span class="o">-</span> <span class="n">currentDigits</span><span class="p">)</span> <span class="o">*</span> <span class="n">N</span><span class="p">;</span> <span class="n">zeroPaddedUpdate</span><span class="p">(</span><span class="n">counts</span><span class="p">,</span> <span class="n">N</span><span class="p">,</span> <span class="n">currentDigits</span><span class="p">);</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">N</span> <span class="o">&lt;</span> <span class="mi">10</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="n">ull</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">N</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">counts</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">++</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">ull</span> <span class="n">powOf10</span> <span class="o">=</span> <span class="k">static_cast</span><span class="o">&lt;</span><span class="n">ull</span><span class="o">&gt;</span><span class="p">(</span><span class="n">powl</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="n">digits</span><span class="p">));</span> <span class="n">ull</span> <span class="n">MSB</span> <span class="o">=</span> <span class="n">N</span> <span class="o">/</span> <span class="n">powOf10</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="n">ull</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">MSB</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">counts</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+=</span> <span class="n">powOf10</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="n">ull</span> <span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="mi">10</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">counts</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">+=</span> <span class="n">powOf10</span> <span class="o">*</span> <span class="n">digits</span> <span class="o">/</span> <span class="mi">10</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="n">counts</span><span class="p">[</span><span class="n">MSB</span><span class="p">]</span> <span class="o">+=</span> <span class="n">N</span> <span class="o">-</span> <span class="p">(</span><span class="n">MSB</span> <span class="o">*</span> <span class="n">powOf10</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="n">zeroPaddedUpdate</span><span class="p">(</span><span class="n">counts</span><span class="p">,</span> <span class="n">N</span> <span class="o">-</span> <span class="p">(</span><span class="n">MSB</span> <span class="o">*</span> <span class="n">powOf10</span><span class="p">),</span> <span class="n">digits</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>실행 결과 ‘틀렸습니다’ 가 떴다.</p> <h3 id="2번째-시도">2번째 시도</h3> <p>코드를 살펴보다가 혹시 <code class="language-plaintext highlighter-rouge">zeroPaddedUpdate</code> 함수에서 <code class="language-plaintext highlighter-rouge">currentDigits</code> 를 구하는 과정에서 $N$ 이 $0$ 일 때 오작동을 일으키나 싶어 따로 처리해주기로 했다.</p> <p>코드는 다음과 같이 수정하였다.</p> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;bits/extc++.h&gt;</span><span class="cp"> </span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">__gnu_pbds</span><span class="p">;</span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">using</span> <span class="n">ll</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">ull</span> <span class="o">=</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">ld</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">double</span><span class="p">;</span> <span class="k">using</span> <span class="n">pll</span> <span class="o">=</span> <span class="n">pair</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;</span><span class="p">;</span> <span class="kt">void</span> <span class="nf">update</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">ull</span><span class="o">&gt;&amp;</span> <span class="n">counts</span><span class="p">,</span> <span class="n">ull</span> <span class="n">N</span><span class="p">);</span> <span class="kt">void</span> <span class="nf">zeroPaddedUpdate</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">ull</span><span class="o">&gt;&amp;</span> <span class="n">counts</span><span class="p">,</span> <span class="n">ull</span> <span class="n">N</span><span class="p">,</span> <span class="n">ull</span> <span class="n">digits</span><span class="p">);</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="n">ull</span> <span class="n">N</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">N</span><span class="p">;</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">ull</span><span class="o">&gt;</span> <span class="n">counts</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="n">update</span><span class="p">(</span><span class="n">counts</span><span class="p">,</span> <span class="n">N</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="n">ull</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="mi">10</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">counts</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">&lt;&lt;</span> <span class="sc">' '</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="kt">void</span> <span class="n">update</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">ull</span><span class="o">&gt;&amp;</span> <span class="n">counts</span><span class="p">,</span> <span class="n">ull</span> <span class="n">N</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">N</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">N</span> <span class="o">&lt;</span> <span class="mi">10</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="n">ull</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">N</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">counts</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">++</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">ull</span> <span class="n">digits</span> <span class="o">=</span> <span class="k">static_cast</span><span class="o">&lt;</span><span class="n">ull</span><span class="o">&gt;</span><span class="p">(</span><span class="n">log10l</span><span class="p">(</span><span class="n">N</span><span class="p">));</span> <span class="n">ull</span> <span class="n">powOf10</span> <span class="o">=</span> <span class="k">static_cast</span><span class="o">&lt;</span><span class="n">ull</span><span class="o">&gt;</span><span class="p">(</span><span class="n">powl</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="n">digits</span><span class="p">));</span> <span class="n">ull</span> <span class="n">MSB</span> <span class="o">=</span> <span class="n">N</span> <span class="o">/</span> <span class="n">powOf10</span><span class="p">;</span> <span class="n">update</span><span class="p">(</span><span class="n">counts</span><span class="p">,</span> <span class="n">powOf10</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="n">ull</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">MSB</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">counts</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+=</span> <span class="n">powOf10</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="n">ull</span> <span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="mi">10</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">counts</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">+=</span> <span class="n">powOf10</span> <span class="o">*</span> <span class="n">digits</span> <span class="o">/</span> <span class="mi">10</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="n">counts</span><span class="p">[</span><span class="n">MSB</span><span class="p">]</span> <span class="o">+=</span> <span class="n">N</span> <span class="o">-</span> <span class="p">(</span><span class="n">MSB</span> <span class="o">*</span> <span class="n">powOf10</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="n">zeroPaddedUpdate</span><span class="p">(</span><span class="n">counts</span><span class="p">,</span> <span class="n">N</span> <span class="o">-</span> <span class="p">(</span><span class="n">MSB</span> <span class="o">*</span> <span class="n">powOf10</span><span class="p">),</span> <span class="n">digits</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="kt">void</span> <span class="n">zeroPaddedUpdate</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">ull</span><span class="o">&gt;&amp;</span> <span class="n">counts</span><span class="p">,</span> <span class="n">ull</span> <span class="n">N</span><span class="p">,</span> <span class="n">ull</span> <span class="n">digits</span><span class="p">)</span> <span class="p">{</span> <span class="n">ull</span> <span class="n">currentDigits</span> <span class="o">=</span> <span class="k">static_cast</span><span class="o">&lt;</span><span class="n">ull</span><span class="o">&gt;</span><span class="p">(</span><span class="n">log10l</span><span class="p">(</span><span class="n">N</span><span class="p">));</span> <span class="k">if</span> <span class="p">(</span><span class="n">N</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="n">counts</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+=</span> <span class="n">digits</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">currentDigits</span> <span class="o">&lt;</span> <span class="n">digits</span><span class="p">)</span> <span class="p">{</span> <span class="n">counts</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+=</span> <span class="p">(</span><span class="n">digits</span> <span class="o">-</span> <span class="n">currentDigits</span><span class="p">)</span> <span class="o">*</span> <span class="n">N</span><span class="p">;</span> <span class="n">zeroPaddedUpdate</span><span class="p">(</span><span class="n">counts</span><span class="p">,</span> <span class="n">N</span><span class="p">,</span> <span class="n">currentDigits</span><span class="p">);</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">N</span> <span class="o">&lt;</span> <span class="mi">10</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="n">ull</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">N</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">counts</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">++</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">ull</span> <span class="n">powOf10</span> <span class="o">=</span> <span class="k">static_cast</span><span class="o">&lt;</span><span class="n">ull</span><span class="o">&gt;</span><span class="p">(</span><span class="n">powl</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="n">digits</span><span class="p">));</span> <span class="n">ull</span> <span class="n">MSB</span> <span class="o">=</span> <span class="n">N</span> <span class="o">/</span> <span class="n">powOf10</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="n">ull</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">MSB</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">counts</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+=</span> <span class="n">powOf10</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="n">ull</span> <span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="mi">10</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">counts</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">+=</span> <span class="n">powOf10</span> <span class="o">*</span> <span class="n">digits</span> <span class="o">/</span> <span class="mi">10</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="n">counts</span><span class="p">[</span><span class="n">MSB</span><span class="p">]</span> <span class="o">+=</span> <span class="n">N</span> <span class="o">-</span> <span class="p">(</span><span class="n">MSB</span> <span class="o">*</span> <span class="n">powOf10</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="n">zeroPaddedUpdate</span><span class="p">(</span><span class="n">counts</span><span class="p">,</span> <span class="n">N</span> <span class="o">-</span> <span class="p">(</span><span class="n">MSB</span> <span class="o">*</span> <span class="n">powOf10</span><span class="p">),</span> <span class="n">digits</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>실행 결과 ‘틀렸습니다’ 가 떴다.</p> <h3 id="3번째-시도">3번째 시도</h3> <p>내가 임의로 정한 $723456$ 를 이용하여 함수들의 로직을 따라가면서 주석을 달며 의도한대로 작동하는지 확인해본 결과, <code class="language-plaintext highlighter-rouge">zeroPaddedUpdate</code> 함수에서 $N$ 이 아닌 $N+1$ 을 곱해야 하는 부분을 발견했다.</p> <p>코드는 다음과 같이 수정하였다.</p> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;bits/extc++.h&gt;</span><span class="cp"> </span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">__gnu_pbds</span><span class="p">;</span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">using</span> <span class="n">ll</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">ull</span> <span class="o">=</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">ld</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">double</span><span class="p">;</span> <span class="k">using</span> <span class="n">pll</span> <span class="o">=</span> <span class="n">pair</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;</span><span class="p">;</span> <span class="kt">void</span> <span class="nf">update</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">ull</span><span class="o">&gt;&amp;</span> <span class="n">counts</span><span class="p">,</span> <span class="n">ull</span> <span class="n">N</span><span class="p">);</span> <span class="kt">void</span> <span class="nf">zeroPaddedUpdate</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">ull</span><span class="o">&gt;&amp;</span> <span class="n">counts</span><span class="p">,</span> <span class="n">ull</span> <span class="n">N</span><span class="p">,</span> <span class="n">ull</span> <span class="n">digits</span><span class="p">);</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="n">ull</span> <span class="n">N</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">N</span><span class="p">;</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">ull</span><span class="o">&gt;</span> <span class="n">counts</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="n">update</span><span class="p">(</span><span class="n">counts</span><span class="p">,</span> <span class="n">N</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="n">ull</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="mi">10</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">counts</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">&lt;&lt;</span> <span class="sc">' '</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="kt">void</span> <span class="n">update</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">ull</span><span class="o">&gt;&amp;</span> <span class="n">counts</span><span class="p">,</span> <span class="n">ull</span> <span class="n">N</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// Example: 723456</span> <span class="k">if</span> <span class="p">(</span><span class="n">N</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">N</span> <span class="o">&lt;</span> <span class="mi">10</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="n">ull</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">N</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">counts</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">++</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">ull</span> <span class="n">digits</span> <span class="o">=</span> <span class="k">static_cast</span><span class="o">&lt;</span><span class="n">ull</span><span class="o">&gt;</span><span class="p">(</span><span class="n">log10l</span><span class="p">(</span><span class="n">N</span><span class="p">));</span> <span class="c1">// 5</span> <span class="n">ull</span> <span class="n">powOf10</span> <span class="o">=</span> <span class="k">static_cast</span><span class="o">&lt;</span><span class="n">ull</span><span class="o">&gt;</span><span class="p">(</span><span class="n">powl</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="n">digits</span><span class="p">));</span> <span class="c1">// 100000</span> <span class="n">ull</span> <span class="n">MSB</span> <span class="o">=</span> <span class="n">N</span> <span class="o">/</span> <span class="n">powOf10</span><span class="p">;</span> <span class="c1">// 7</span> <span class="n">update</span><span class="p">(</span><span class="n">counts</span><span class="p">,</span> <span class="n">powOf10</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span> <span class="c1">// 1 ~ 99999</span> <span class="k">for</span> <span class="p">(</span><span class="n">ull</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">MSB</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// 100000 ~ 199999, 200000 ~ 299999, ..., 600000 ~ 699999</span> <span class="n">counts</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+=</span> <span class="n">powOf10</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="n">ull</span> <span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="mi">10</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">counts</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">+=</span> <span class="n">powOf10</span> <span class="o">*</span> <span class="n">digits</span> <span class="o">/</span> <span class="mi">10</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="c1">// 700000 ~ 723456</span> <span class="n">counts</span><span class="p">[</span><span class="n">MSB</span><span class="p">]</span> <span class="o">+=</span> <span class="n">N</span> <span class="o">-</span> <span class="p">(</span><span class="n">MSB</span> <span class="o">*</span> <span class="n">powOf10</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="n">zeroPaddedUpdate</span><span class="p">(</span><span class="n">counts</span><span class="p">,</span> <span class="n">N</span> <span class="o">-</span> <span class="p">(</span><span class="n">MSB</span> <span class="o">*</span> <span class="n">powOf10</span><span class="p">),</span> <span class="n">digits</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span> <span class="c1">// 00000 ~ 23456</span> <span class="p">}</span> <span class="p">}</span> <span class="kt">void</span> <span class="n">zeroPaddedUpdate</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">ull</span><span class="o">&gt;&amp;</span> <span class="n">counts</span><span class="p">,</span> <span class="n">ull</span> <span class="n">N</span><span class="p">,</span> <span class="n">ull</span> <span class="n">digits</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// Example: 23456</span> <span class="n">ull</span> <span class="n">currentDigits</span> <span class="o">=</span> <span class="k">static_cast</span><span class="o">&lt;</span><span class="n">ull</span><span class="o">&gt;</span><span class="p">(</span><span class="n">log10l</span><span class="p">(</span><span class="n">N</span><span class="p">));</span> <span class="c1">// 4</span> <span class="k">if</span> <span class="p">(</span><span class="n">N</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// Example: 00000</span> <span class="n">counts</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+=</span> <span class="n">digits</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">currentDigits</span> <span class="o">&lt;</span> <span class="n">digits</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// Example: 00234</span> <span class="n">counts</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+=</span> <span class="p">(</span><span class="n">digits</span> <span class="o">-</span> <span class="n">currentDigits</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">N</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span> <span class="n">zeroPaddedUpdate</span><span class="p">(</span><span class="n">counts</span><span class="p">,</span> <span class="n">N</span><span class="p">,</span> <span class="n">currentDigits</span><span class="p">);</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">N</span> <span class="o">&lt;</span> <span class="mi">10</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="n">ull</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">N</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">counts</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">++</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">ull</span> <span class="n">powOf10</span> <span class="o">=</span> <span class="k">static_cast</span><span class="o">&lt;</span><span class="n">ull</span><span class="o">&gt;</span><span class="p">(</span><span class="n">powl</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="n">digits</span><span class="p">));</span> <span class="c1">// 10000</span> <span class="n">ull</span> <span class="n">MSB</span> <span class="o">=</span> <span class="n">N</span> <span class="o">/</span> <span class="n">powOf10</span><span class="p">;</span> <span class="c1">// 2</span> <span class="k">for</span> <span class="p">(</span><span class="n">ull</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">MSB</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// 00000 ~ 09999, 10000 ~ 19999</span> <span class="n">counts</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+=</span> <span class="n">powOf10</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="n">ull</span> <span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="mi">10</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">counts</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">+=</span> <span class="n">powOf10</span> <span class="o">*</span> <span class="n">digits</span> <span class="o">/</span> <span class="mi">10</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="c1">// 20000 ~ 23456</span> <span class="n">counts</span><span class="p">[</span><span class="n">MSB</span><span class="p">]</span> <span class="o">+=</span> <span class="n">N</span> <span class="o">-</span> <span class="p">(</span><span class="n">MSB</span> <span class="o">*</span> <span class="n">powOf10</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="n">zeroPaddedUpdate</span><span class="p">(</span><span class="n">counts</span><span class="p">,</span> <span class="n">N</span> <span class="o">-</span> <span class="p">(</span><span class="n">MSB</span> <span class="o">*</span> <span class="n">powOf10</span><span class="p">),</span> <span class="n">digits</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span> <span class="c1">// 0000 ~ 3456</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>그러자 모든 테스트 케이스를 통과하고 ‘맞았습니다’가 나오는 것을 확인할 수 있었다.</p> <h2 id="마무리">마무리</h2> <p>수들의 구간을 분할하는 아이디어를 떠올리는 것 자체는 어렵진 않았지만, 이를 실제로 구현하는게 빡센 문제였다. 복잡한 수학 지식을 요구하지 않아도 Platinum V 난이도를 받을 수 있다는 걸 보여주는 매콤한 문제였던 것 같다…</p> <p>오늘의 PS는 여기까지!</p> <hr /> <p><a name="footnote_1">1</a>: <a href="https://www.acmicpc.net/problem/1019">https://www.acmicpc.net/problem/1019</a></p> Sat, 24 Aug 2024 23:59:00 +0900 https://choicube84.github.io/study/2024/08/24/baekjoon_1019.html https://choicube84.github.io/study/2024/08/24/baekjoon_1019.html problem_solving Study 백준 13544번 <h1 id="백준-13544번">백준 13544번</h1> <p>오늘 풀어본 문제는 백준의 13544번 문제<sup><a href="#footnote_1">1</a></sup>이다. 문제 풀이에 사용한 언어는 C++ 이다.</p> <h2 id="solvedac-기준-class">solved.ac 기준 CLASS</h2> <p><img src="https://static.solved.ac/class/c7.svg" width="50%" height="50%" alt="CLASS 7" /></p> <h2 id="문제-정보">문제 정보</h2> <p>이 문제의 내용과 조건은 다음과 같다.</p> <h3 id="문제">문제</h3> <p>길이가 $N$ 인 수열 $A_1,\ A_2,\ \cdots,\ A_N$ 이 주어진다. 이때, 다음 쿼리를 수행하는 프로그램을 작성하시오.</p> <ul> <li>$i\ j\ k$: $A_i,\ A_{i+1},\ \cdots,\ A_j$ 로 이루어진 부분 수열 중에서 $k$ 보다 큰 원소의 개수를 출력한다.</li> </ul> <h3 id="입력">입력</h3> <p>첫째 줄에 수열의 크기 $N$ $(1 \le N \le 100,000)$ 이 주어진다.</p> <p>둘째 줄에는 $A_1,\ A_2,\ \cdots,\ A_N$ 이 주어진다. $(1 \le A_i \le 109)$</p> <p>셋째 줄에는 쿼리의 개수 $M$ $(1 \le M \le 100,000)$ 이 주어진다.</p> <p>넷째 줄부터 $M$ 개의 줄에는 $a, b, c$ 가 주어진다. $a, b, c$ 를 이용해 쿼리를 만들어야 한다.</p> <ul> <li> <p>$i = a\ \text{xor}\ \text{last_ans}$</p> </li> <li> <p>$j = b\ \text{xor}\ \text{last_ans}$</p> </li> <li> <p>$k = c\ \text{xor}\ \text{last_ans}$</p> </li> </ul> <p>last_ans는 이전 쿼리의 정답이며, 가장 처음에는 $0$ 이다. xor한 결과는 $1 \le i \le j \le n,\ 1 \le k \le 10^9$ 을 만족한다.</p> <h3 id="출력">출력</h3> <p>각각의 쿼리마다 정답을 한 줄에 하나씩 출력한다.</p> <h2 id="풀이과정">풀이과정</h2> <h3 id="1번째-시도">1번째 시도</h3> <p>문제를 가만히 보니 그냥 백준 13537번(수열과 쿼리 1) 문제에서 쿼리 입력 부분만 조금 손보면 똑같다는 것을 알 수 있었다! 그래서 예전에 푼 코드를 그대로 가져와서 조금 수정만 해서 제출하기로 하였다.</p> <p>코드는 다음과 같이 작성하였다. 제출할 때는 헤더파일의 코드를 붙여넣어 제출하였다.</p> <h4 id="merge_sort_treehpp">merge_sort_tree.hpp</h4> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#ifndef __MERGE_SORT_TREE_HPP__ #define __MERGE_SORT_TREE_HPP__ </span> <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">&gt;</span> <span class="k">class</span> <span class="nc">MergeSortTree</span> <span class="p">{</span> <span class="nl">private:</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&gt;</span> <span class="n">tree</span><span class="p">;</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">arr</span><span class="p">;</span> <span class="kt">size_t</span> <span class="n">n</span><span class="p">;</span> <span class="kt">void</span> <span class="n">build</span><span class="p">(</span><span class="kt">size_t</span> <span class="n">idx</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">left</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">right</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">left</span> <span class="o">==</span> <span class="n">right</span><span class="p">)</span> <span class="p">{</span> <span class="n">tree</span><span class="p">[</span><span class="n">idx</span><span class="p">].</span><span class="n">resize</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span> <span class="n">tree</span><span class="p">[</span><span class="n">idx</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">left</span><span class="p">];</span> <span class="k">return</span><span class="p">;</span> <span class="p">}</span> <span class="kt">size_t</span> <span class="n">mid</span> <span class="o">=</span> <span class="p">(</span><span class="n">left</span> <span class="o">+</span> <span class="n">right</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span><span class="p">;</span> <span class="n">build</span><span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">idx</span><span class="p">,</span> <span class="n">left</span><span class="p">,</span> <span class="n">mid</span><span class="p">);</span> <span class="n">build</span><span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">idx</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">mid</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">right</span><span class="p">);</span> <span class="n">tree</span><span class="p">[</span><span class="n">idx</span><span class="p">].</span><span class="n">resize</span><span class="p">(</span><span class="n">tree</span><span class="p">[</span><span class="mi">2</span> <span class="o">*</span> <span class="n">idx</span><span class="p">].</span><span class="n">size</span><span class="p">()</span> <span class="o">+</span> <span class="n">tree</span><span class="p">[</span><span class="mi">2</span> <span class="o">*</span> <span class="n">idx</span> <span class="o">+</span> <span class="mi">1</span><span class="p">].</span><span class="n">size</span><span class="p">());</span> <span class="n">std</span><span class="o">::</span><span class="n">merge</span><span class="p">(</span><span class="n">tree</span><span class="p">[</span><span class="mi">2</span> <span class="o">*</span> <span class="n">idx</span><span class="p">].</span><span class="n">begin</span><span class="p">(),</span> <span class="n">tree</span><span class="p">[</span><span class="mi">2</span> <span class="o">*</span> <span class="n">idx</span><span class="p">].</span><span class="n">end</span><span class="p">(),</span> <span class="n">tree</span><span class="p">[</span><span class="mi">2</span> <span class="o">*</span> <span class="n">idx</span> <span class="o">+</span> <span class="mi">1</span><span class="p">].</span><span class="n">begin</span><span class="p">(),</span> <span class="n">tree</span><span class="p">[</span><span class="mi">2</span> <span class="o">*</span> <span class="n">idx</span> <span class="o">+</span> <span class="mi">1</span><span class="p">].</span><span class="n">end</span><span class="p">(),</span> <span class="n">tree</span><span class="p">[</span><span class="n">idx</span><span class="p">].</span><span class="n">begin</span><span class="p">());</span> <span class="p">}</span> <span class="kt">size_t</span> <span class="n">query</span><span class="p">(</span><span class="kt">size_t</span> <span class="n">i</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">j</span><span class="p">,</span> <span class="k">const</span> <span class="n">T</span><span class="o">&amp;</span> <span class="n">k</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">node</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">currentLeft</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">currentRight</span><span class="p">)</span> <span class="p">{</span> <span class="kt">size_t</span> <span class="n">result</span><span class="p">;</span> <span class="k">if</span> <span class="p">(</span><span class="n">j</span> <span class="o">&lt;</span> <span class="n">currentLeft</span> <span class="o">||</span> <span class="n">currentRight</span> <span class="o">&lt;</span> <span class="n">i</span><span class="p">)</span> <span class="p">{</span> <span class="n">result</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">i</span> <span class="o">&lt;=</span> <span class="n">currentLeft</span> <span class="o">&amp;&amp;</span> <span class="n">currentRight</span> <span class="o">&lt;=</span> <span class="n">j</span><span class="p">)</span> <span class="p">{</span> <span class="n">result</span> <span class="o">=</span> <span class="n">tree</span><span class="p">[</span><span class="n">node</span><span class="p">].</span><span class="n">end</span><span class="p">()</span> <span class="o">-</span> <span class="n">upper_bound</span><span class="p">(</span><span class="n">tree</span><span class="p">[</span><span class="n">node</span><span class="p">].</span><span class="n">begin</span><span class="p">(),</span> <span class="n">tree</span><span class="p">[</span><span class="n">node</span><span class="p">].</span><span class="n">end</span><span class="p">(),</span> <span class="n">k</span><span class="p">);</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="kt">size_t</span> <span class="n">mid</span> <span class="o">=</span> <span class="p">(</span><span class="n">currentLeft</span> <span class="o">+</span> <span class="n">currentRight</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span><span class="p">;</span> <span class="n">result</span> <span class="o">=</span> <span class="n">query</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">node</span><span class="p">,</span> <span class="n">currentLeft</span><span class="p">,</span> <span class="n">mid</span><span class="p">)</span> <span class="o">+</span> <span class="n">query</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">node</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">mid</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">currentRight</span><span class="p">);</span> <span class="p">}</span> <span class="k">return</span> <span class="n">result</span><span class="p">;</span> <span class="p">}</span> <span class="nl">public:</span> <span class="n">MergeSortTree</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&amp;</span> <span class="n">a</span><span class="p">)</span> <span class="o">:</span> <span class="n">arr</span><span class="p">(</span><span class="n">a</span><span class="p">),</span> <span class="n">n</span><span class="p">(</span><span class="n">a</span><span class="p">.</span><span class="n">size</span><span class="p">())</span> <span class="p">{</span> <span class="n">tree</span><span class="p">.</span><span class="n">resize</span><span class="p">(</span><span class="mi">4</span> <span class="o">*</span> <span class="n">n</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span> <span class="n">build</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span> <span class="p">}</span> <span class="kt">size_t</span> <span class="n">query</span><span class="p">(</span><span class="kt">size_t</span> <span class="n">i</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">j</span><span class="p">,</span> <span class="k">const</span> <span class="n">T</span><span class="o">&amp;</span> <span class="n">k</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="n">query</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span> <span class="p">}</span> <span class="p">};</span> <span class="cp">#endif // __MERGE_SORT_TREE_HPP__ </span></code></pre></div></div> <h4 id="mainhpp">main.hpp</h4> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;bits/stdc++.h&gt;</span><span class="cp"> #include</span> <span class="cpf">"merge_sort_tree.hpp"</span><span class="cp"> </span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">ios</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="n">cout</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="kt">int</span> <span class="n">N</span><span class="p">,</span> <span class="n">M</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">N</span><span class="p">;</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">A</span><span class="p">(</span><span class="n">N</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">N</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="p">}</span> <span class="n">MergeSortTree</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">mst</span><span class="p">(</span><span class="n">A</span><span class="p">);</span> <span class="kt">int</span> <span class="n">last_ans</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">M</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">query</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">query</span> <span class="o">&lt;</span> <span class="n">M</span><span class="p">;</span> <span class="n">query</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="kt">int</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">a</span> <span class="o">&gt;&gt;</span> <span class="n">b</span> <span class="o">&gt;&gt;</span> <span class="n">c</span><span class="p">;</span> <span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="n">a</span> <span class="o">^</span> <span class="n">last_ans</span><span class="p">;</span> <span class="kt">int</span> <span class="n">j</span> <span class="o">=</span> <span class="n">b</span> <span class="o">^</span> <span class="n">last_ans</span><span class="p">;</span> <span class="kt">int</span> <span class="n">k</span> <span class="o">=</span> <span class="n">c</span> <span class="o">^</span> <span class="n">last_ans</span><span class="p">;</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">mst</span><span class="p">.</span><span class="n">query</span><span class="p">(</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="n">j</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="n">k</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> </code></pre></div></div> <p>실행 결과 ‘틀렸습니다’ 가 떴다.</p> <h3 id="2번째-시도">2번째 시도</h3> <p>코드를 다시 보니 <code class="language-plaintext highlighter-rouge">last_ans</code> 변수를 업데이트 해주는 걸 깜빡했다는 걸 바로 알 수 있었다.</p> <p>코드는 다음과 같이 수정하였고, <code class="language-plaintext highlighter-rouge">main.cpp</code> 파일만 수정하였다.</p> <h4 id="maincpp">main.cpp</h4> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;bits/stdc++.h&gt;</span><span class="cp"> #include</span> <span class="cpf">"merge_sort_tree.hpp"</span><span class="cp"> </span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">ios</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="n">cout</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="kt">int</span> <span class="n">N</span><span class="p">,</span> <span class="n">M</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">N</span><span class="p">;</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">A</span><span class="p">(</span><span class="n">N</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">N</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="p">}</span> <span class="n">MergeSortTree</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">mst</span><span class="p">(</span><span class="n">A</span><span class="p">);</span> <span class="kt">int</span> <span class="n">last_ans</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">M</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">query</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">query</span> <span class="o">&lt;</span> <span class="n">M</span><span class="p">;</span> <span class="n">query</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="kt">int</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">a</span> <span class="o">&gt;&gt;</span> <span class="n">b</span> <span class="o">&gt;&gt;</span> <span class="n">c</span><span class="p">;</span> <span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="n">a</span> <span class="o">^</span> <span class="n">last_ans</span><span class="p">;</span> <span class="kt">int</span> <span class="n">j</span> <span class="o">=</span> <span class="n">b</span> <span class="o">^</span> <span class="n">last_ans</span><span class="p">;</span> <span class="kt">int</span> <span class="n">k</span> <span class="o">=</span> <span class="n">c</span> <span class="o">^</span> <span class="n">last_ans</span><span class="p">;</span> <span class="n">last_ans</span> <span class="o">=</span> <span class="n">mst</span><span class="p">.</span><span class="n">query</span><span class="p">(</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="n">j</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="n">k</span><span class="p">);</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">last_ans</span> <span class="o">&lt;&lt;</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> </code></pre></div></div> <p>그러자 모든 테스트 케이스를 통과하고 ‘맞았습니다’가 나오는 것을 확인할 수 있었다.</p> <h2 id="마무리">마무리</h2> <p>원래 내가 이 문제를 풀려고 했던 의도는 merge sort tree가 segment tree의 일종이라는 것을 깨달았고, 모노이드를 적절하게 구성하여 merge sort tree 를 사용해야 하는 문제를 풀어보려고 했던 것이다. 그런데 이미 잘 짜둔 코드가 있어서 그냥 사용하게 되었고, 여기서 원래 사용하려던 방법을 간단히 이야기 해보려고 한다.</p> <p>우선 merge sort tree 는 전체 수열에서 특정 구간의 정렬된 수열을 쿼리로 반환하게 되는데, 이 때 우리는 모노이드의 원소, 연산, 항등원을 다음과 같이 구성할 수 있다.</p> <ul> <li> <p>원소: 전체 수열에 들어갈 수 있는 각 수들의 집합의 power set이 이 모노이드의 원소로 사용된다.</p> </li> <li> <p>연산: merge sort 에서 정렬된 두 부분 수열을 합치는 연산을 수행한다. 이 연산은 닫혀있고, 결합 법칙이 성립한다.</p> </li> <li> <p>항등원: 텅 빈 배열이 항등원이 된다. 어떤 부분 수열과 merge 연산을 적용하여도 그 부분 수열이 그대로 나오게 되어 항등원임을 알 수 있다.</p> </li> </ul> <p>원래는 이런 방식으로 모노이드를 구성해서 풀려고 했던 것이다. <del>Actual implementation is left as an exercise to the reader.</del></p> <p>내가 만든 머지 소트 자료구조는 내 레포지토리<sup><a href="#footnote_2">2</a></sup>에서 확인할 수 있다. 다만 앞으로 머지 소트 트리를 구현할 때는 세그먼트 트리에 적절한 모노이드를 만드는 방식으로 구현할 것이다.</p> <p>오늘의 PS는 여기까지!</p> <hr /> <p><a name="footnote_1">1</a>: <a href="https://www.acmicpc.net/problem/13544">https://www.acmicpc.net/problem/13544</a><br /> <a name="footnote_2">2</a>: <a href="https://github.com/ChoiCube84/baekjoon-solutions/blob/main/C%2B%2B/13544/merge_sort_tree.hpp">https://github.com/ChoiCube84/baekjoon-solutions/blob/main/C%2B%2B/13544/merge_sort_tree.hpp</a></p> Tue, 13 Aug 2024 23:59:00 +0900 https://choicube84.github.io/study/2024/08/13/baekjoon_13544.html https://choicube84.github.io/study/2024/08/13/baekjoon_13544.html problem_solving Study 백준 17401번 <h1 id="백준-17401번">백준 17401번</h1> <p>오늘 풀어본 문제는 백준의 17401번 문제<sup><a href="#footnote_1">1</a></sup>이다. 문제 풀이에 사용한 언어는 C++ 이다.</p> <h2 id="solvedac-기준-class">solved.ac 기준 CLASS</h2> <p><img src="https://static.solved.ac/class/c6.svg" width="50%" height="50%" alt="CLASS 6" /></p> <h2 id="문제-정보">문제 정보</h2> <p>이 문제의 내용과 조건은 다음과 같다.</p> <h3 id="문제">문제</h3> <p>사람의 세포 수, 약 $37$ 조 개. 세포들은 몸 속에서 오늘도 열심히 일하고 있다. 그중에서도 우리의 적혈구는 혈관을 타고 돌아다니며 산소와 영양소를 운반해주는 중요한 역할을 맡고있다.</p> <p>적혈구는 심장이나 폐 같은 거점들을 돌아다니면서 산소와 영양분을 운반한다. 몸 속에는 총 $N$ 개의 거점이 있고, 몇몇 거점은 통로를 통해 서로 이어져 있다. 거점 사이의 통로를 통과하는데는 $1$ 초가 걸린다. 하지만 혈관의 곳곳에는 판막이나 공사중인 부분들이 있기 때문에 매 초 거점 사이의 연결관계가 바뀐다. 그럼에도 불구하고 몸의 곳곳이 산소와 영양분을 필요로 하므로 적혈구는 가만히 있을 수 없으며, 매 초 통로를 무조건 하나 타야 한다. 일부 통로는 출발 거점과 도착 거점이 같을 수도 있다. 일부 거점의 특정 순간에는 나가는 통로가 없을 수도 있는데, 이 때는 도착한지 $1$ 초 후에 파괴되어 몸과 다시 하나가 된다. 잔혹하지만 우리의 몸은 이렇게 돌아간다.</p> <p>우리의 적혈구는 매 순간 변하는 몸속 혈관 지도에 길을 헤매지만 그래도 최선을 다해서 하루하루 열심히 일을 하고 있다. 옆에 있던 백혈구가 길을 헤매는 적혈구를 보고 도와주고 싶다는 생각을 했다.</p> <p>수십 시간의 유주 경험을 통해 백혈구는 몸속 혈관 지도가 $T$ 초를 주기로 반복된다는 것을 알게 되었다. 이 사실을 정리해서 적혈구가 거점 $A$ 에서 출발하여 정확히 $D$ 초 후 거점 $B$ 에 도달하게 되는 경우의 수를 모든 거점의 순서쌍에 대해 구해주고자 하지만 너무나도 단세포이기 때문에 머리가 나빠서 계산을 하지 못했다. 한 경로는, $D$ 초 동안 통과한 통로의 순열로 정의된다. 백혈구를 도와서 적혈구가 $D$ 초 동안 한 거점에서 다른 거점까지 움직일 수 있는 경우의 수를 구해주자!</p> <h3 id="입력">입력</h3> <p>첫 번째 줄에는 백혈구가 알아낸 혈관 지도들의 주기인 자연수 T 와 거점의 개수인 자연수 N, 적혈구가 움직이는 시간인 정수 D 가 공백으로 구분되어 주어진다. $(1 \le T \le 100,\ 2 \le N \le 20, 0 \le D \le 109)$</p> <p>그 뒤 거점 사이의 연결 관계를 나타내는 혈관 지도 $T$ 개가 순서대로 $1$ 번부터 $T$ 번까지 주어지는데, 혈관 지도가 주어지는 형식은 다음과 같다.</p> <ul> <li> <p>첫 번째 줄에는 거점 사이를 잇는 혈관의 개수인 자연수 $M_i$ 가 주어진다. $(0 \le Mi \le N2)$</p> </li> <li> <p>그 뒤 $M_i$ 개의 줄에 걸쳐 세 자연수 $a,\ b,\ c$ 가 공백으로 구분되어 주어진다. 이는 거점 $a$ 에서 거점 $b$ 로 가는 서로 다른 단방향 통로가 $c$ 개 있음을 의미한다. $(1 \le a, b \le N, 1 \le c \le 1000)$</p> </li> <li> <p>매 혈관 지도에 중복된 연결 관계는 주어지지 않는다.</p> </li> </ul> <p>$i4 초에서 $(i+1)$ 초 동안 이동할 때는 $(i % T + 1)$ 번 혈관 지도가 적용된다. $i % T$ 는 $i$ 를 $T$ 로 나눈 나머지를 의미한다.</p> <h3 id="출력">출력</h3> <p>출력은 $N$ 개의 줄로 구성되며, $i$ 번째 줄에는 $N$ 개의 정수 $x_{i1},\ x_{i2}, \cdots, $x_{iN}$ 를 공백으로 구분하여 출력해야 한다. $x_{ij}$ 는 $0$ 초 때 거점 $i$ 에서 출발하여 정확히 $D$ 초 때 거점 $j$ 에 위치하게 되는 경로의 수를 $1,000,000,007$ 로 나눈 나머지이다.</p> <h2 id="풀이과정">풀이과정</h2> <h3 id="1번째-시도">1번째 시도</h3> <p>특정 지점에서 다른 지점으로 이동 가능한 경우의 수를 구하는 문제를 보고, 행렬의 거듭제곱을 이용해야 한다는 것을 알 수 있었다. 이런 유형의 다른 문제들과 차별되는 부분은, 혈관 지도가 주기를 가지고 바뀐다는 것인데, 이건 그냥 한 주기 내의 모든 행렬들을 미리 곱해놓고 그걸 거듭제곱 한 뒤, 한 주기가 되지 않는 남은 시간 만큼 행렬들을 곱하면 될 것이라고 생각하였다.</p> <p>코드는 다음과 같이 작성하였다. 제출할 때는 헤더파일의 코드를 붙여넣어 제출하였다.</p> <h4 id="matrixhpp">matrix.hpp</h4> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#ifndef __MATRIX_HPP__ #define __MATRIX_HPP__ </span> <span class="cp">#include</span> <span class="cpf">&lt;utility&gt;</span><span class="cp"> </span> <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">&gt;</span> <span class="k">class</span> <span class="nc">Matrix</span> <span class="p">{</span> <span class="nl">private:</span> <span class="kt">size_t</span> <span class="n">row</span><span class="p">;</span> <span class="kt">size_t</span> <span class="n">column</span><span class="p">;</span> <span class="n">T</span> <span class="n">mod</span><span class="p">;</span> <span class="n">T</span><span class="o">**</span> <span class="n">elements</span><span class="p">;</span> <span class="kt">void</span> <span class="n">clearElements</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">row</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">delete</span><span class="p">[]</span> <span class="n">elements</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="p">}</span> <span class="k">delete</span><span class="p">[]</span> <span class="n">elements</span><span class="p">;</span> <span class="p">}</span> <span class="nl">public:</span> <span class="n">Matrix</span><span class="p">()</span> <span class="o">:</span> <span class="n">row</span><span class="p">(</span><span class="mi">0</span><span class="p">),</span> <span class="n">column</span><span class="p">(</span><span class="mi">0</span><span class="p">),</span> <span class="n">mod</span><span class="p">(</span><span class="mi">0</span><span class="p">),</span> <span class="n">elements</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">)</span> <span class="p">{}</span> <span class="n">Matrix</span><span class="p">(</span><span class="kt">size_t</span> <span class="n">row</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">column</span><span class="p">,</span> <span class="kt">bool</span> <span class="n">identity</span> <span class="o">=</span> <span class="nb">false</span><span class="p">,</span> <span class="n">T</span> <span class="n">mod</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="o">:</span> <span class="n">row</span><span class="p">(</span><span class="n">row</span><span class="p">),</span> <span class="n">column</span><span class="p">(</span><span class="n">column</span><span class="p">),</span> <span class="n">mod</span><span class="p">(</span><span class="n">mod</span><span class="p">)</span> <span class="p">{</span> <span class="n">elements</span> <span class="o">=</span> <span class="k">new</span> <span class="n">T</span> <span class="o">*</span> <span class="p">[</span><span class="n">row</span><span class="p">];</span> <span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">row</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">elements</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="k">new</span> <span class="n">T</span><span class="p">[</span><span class="n">column</span><span class="p">];</span> <span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="n">column</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">elements</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">identity</span> <span class="o">?</span> <span class="p">(</span><span class="n">i</span> <span class="o">==</span> <span class="n">j</span> <span class="o">?</span> <span class="mi">1</span> <span class="o">:</span> <span class="mi">0</span><span class="p">)</span> <span class="o">:</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="n">Matrix</span><span class="p">(</span><span class="k">const</span> <span class="n">Matrix</span><span class="o">&amp;</span> <span class="n">other</span><span class="p">)</span> <span class="o">:</span> <span class="n">mod</span><span class="p">(</span><span class="n">other</span><span class="p">.</span><span class="n">mod</span><span class="p">)</span> <span class="p">{</span> <span class="k">this</span><span class="o">-&gt;</span><span class="n">row</span> <span class="o">=</span> <span class="n">other</span><span class="p">.</span><span class="n">row</span><span class="p">;</span> <span class="k">this</span><span class="o">-&gt;</span><span class="n">column</span> <span class="o">=</span> <span class="n">other</span><span class="p">.</span><span class="n">column</span><span class="p">;</span> <span class="n">elements</span> <span class="o">=</span> <span class="k">new</span> <span class="n">T</span> <span class="o">*</span> <span class="p">[</span><span class="n">row</span><span class="p">];</span> <span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">row</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">elements</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="k">new</span> <span class="n">T</span><span class="p">[</span><span class="n">column</span><span class="p">];</span> <span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="n">column</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">elements</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">other</span><span class="p">.</span><span class="n">elements</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">];</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="o">~</span><span class="n">Matrix</span><span class="p">()</span> <span class="p">{</span> <span class="n">clearElements</span><span class="p">();</span> <span class="p">}</span> <span class="n">T</span><span class="o">*</span> <span class="k">operator</span><span class="p">[]</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">idx</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="n">elements</span><span class="p">[</span><span class="n">idx</span><span class="p">];</span> <span class="p">}</span> <span class="k">const</span> <span class="n">T</span><span class="o">*</span> <span class="k">operator</span><span class="p">[]</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">idx</span><span class="p">)</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">elements</span><span class="p">[</span><span class="n">idx</span><span class="p">];</span> <span class="p">}</span> <span class="n">Matrix</span><span class="o">&amp;</span> <span class="k">operator</span><span class="o">=</span> <span class="p">(</span><span class="k">const</span> <span class="n">Matrix</span><span class="o">&amp;</span> <span class="n">other</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="k">this</span> <span class="o">==</span> <span class="o">&amp;</span><span class="n">other</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="o">*</span><span class="k">this</span><span class="p">;</span> <span class="p">}</span> <span class="n">clearElements</span><span class="p">();</span> <span class="k">this</span><span class="o">-&gt;</span><span class="n">row</span> <span class="o">=</span> <span class="n">other</span><span class="p">.</span><span class="n">row</span><span class="p">;</span> <span class="k">this</span><span class="o">-&gt;</span><span class="n">column</span> <span class="o">=</span> <span class="n">other</span><span class="p">.</span><span class="n">column</span><span class="p">;</span> <span class="n">elements</span> <span class="o">=</span> <span class="k">new</span> <span class="n">T</span> <span class="o">*</span> <span class="p">[</span><span class="n">row</span><span class="p">];</span> <span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">row</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">elements</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="k">new</span> <span class="n">T</span><span class="p">[</span><span class="n">column</span><span class="p">];</span> <span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="n">column</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">elements</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">other</span><span class="p">.</span><span class="n">elements</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">];</span> <span class="p">}</span> <span class="p">}</span> <span class="k">return</span> <span class="o">*</span><span class="k">this</span><span class="p">;</span> <span class="p">}</span> <span class="n">Matrix</span> <span class="k">operator</span><span class="o">+</span> <span class="p">(</span><span class="k">const</span> <span class="n">Matrix</span><span class="o">&amp;</span> <span class="n">other</span><span class="p">)</span> <span class="p">{</span> <span class="n">Matrix</span> <span class="n">result</span><span class="p">(</span><span class="o">*</span><span class="k">this</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">row</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="n">column</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">result</span><span class="p">.</span><span class="n">elements</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span> <span class="o">+=</span> <span class="n">other</span><span class="p">.</span><span class="n">elements</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">];</span> <span class="k">if</span> <span class="p">(</span><span class="n">mod</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="n">result</span><span class="p">.</span><span class="n">elements</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span> <span class="o">%=</span> <span class="n">mod</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="k">return</span> <span class="n">result</span><span class="p">;</span> <span class="p">}</span> <span class="n">Matrix</span><span class="o">&amp;</span> <span class="k">operator</span><span class="o">+=</span> <span class="p">(</span><span class="k">const</span> <span class="n">Matrix</span><span class="o">&amp;</span> <span class="n">other</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">row</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="n">column</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">elements</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span> <span class="o">+=</span> <span class="n">other</span><span class="p">.</span><span class="n">elements</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">];</span> <span class="k">if</span> <span class="p">(</span><span class="n">mod</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="n">elements</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span> <span class="o">%=</span> <span class="n">mod</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="k">return</span> <span class="o">*</span><span class="k">this</span><span class="p">;</span> <span class="p">}</span> <span class="n">Matrix</span> <span class="k">operator</span><span class="o">-</span> <span class="p">(</span><span class="k">const</span> <span class="n">Matrix</span><span class="o">&amp;</span> <span class="n">other</span><span class="p">)</span> <span class="p">{</span> <span class="n">Matrix</span> <span class="n">result</span><span class="p">(</span><span class="o">*</span><span class="k">this</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">row</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="n">column</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">result</span><span class="p">.</span><span class="n">elements</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span> <span class="o">-=</span> <span class="n">other</span><span class="p">.</span><span class="n">elements</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">];</span> <span class="k">if</span> <span class="p">(</span><span class="n">mod</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="n">result</span><span class="p">.</span><span class="n">elements</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span> <span class="o">%=</span> <span class="n">mod</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="k">return</span> <span class="n">result</span><span class="p">;</span> <span class="p">}</span> <span class="n">Matrix</span><span class="o">&amp;</span> <span class="k">operator</span><span class="o">-=</span> <span class="p">(</span><span class="k">const</span> <span class="n">Matrix</span><span class="o">&amp;</span> <span class="n">other</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">row</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="n">column</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">elements</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span> <span class="o">-=</span> <span class="n">other</span><span class="p">.</span><span class="n">elements</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">];</span> <span class="k">if</span> <span class="p">(</span><span class="n">mod</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="n">elements</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span> <span class="o">%=</span> <span class="n">mod</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="k">return</span> <span class="o">*</span><span class="k">this</span><span class="p">;</span> <span class="p">}</span> <span class="n">Matrix</span> <span class="k">operator</span><span class="o">*</span> <span class="p">(</span><span class="k">const</span> <span class="n">Matrix</span><span class="o">&amp;</span> <span class="n">other</span><span class="p">)</span> <span class="p">{</span> <span class="n">Matrix</span> <span class="n">result</span><span class="p">(</span><span class="k">this</span><span class="o">-&gt;</span><span class="n">row</span><span class="p">,</span> <span class="n">other</span><span class="p">.</span><span class="n">column</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">result</span><span class="p">.</span><span class="n">row</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="n">result</span><span class="p">.</span><span class="n">column</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">result</span><span class="p">.</span><span class="n">elements</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">k</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">k</span> <span class="o">&lt;</span> <span class="k">this</span><span class="o">-&gt;</span><span class="n">column</span><span class="p">;</span> <span class="n">k</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">T</span> <span class="n">product</span> <span class="o">=</span> <span class="k">this</span><span class="o">-&gt;</span><span class="n">elements</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">k</span><span class="p">]</span> <span class="o">*</span> <span class="n">other</span><span class="p">.</span><span class="n">elements</span><span class="p">[</span><span class="n">k</span><span class="p">][</span><span class="n">j</span><span class="p">];</span> <span class="k">if</span> <span class="p">(</span><span class="n">mod</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="n">product</span> <span class="o">%=</span> <span class="n">mod</span><span class="p">;</span> <span class="p">}</span> <span class="n">result</span><span class="p">.</span><span class="n">elements</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span> <span class="o">+=</span> <span class="n">product</span><span class="p">;</span> <span class="k">if</span> <span class="p">(</span><span class="n">mod</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="n">result</span><span class="p">.</span><span class="n">elements</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span> <span class="o">%=</span> <span class="n">mod</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="k">return</span> <span class="n">result</span><span class="p">;</span> <span class="p">}</span> <span class="n">Matrix</span> <span class="n">power</span><span class="p">(</span><span class="kt">size_t</span> <span class="n">exponent</span><span class="p">)</span> <span class="p">{</span> <span class="n">Matrix</span> <span class="n">base</span><span class="p">(</span><span class="o">*</span><span class="k">this</span><span class="p">);</span> <span class="n">Matrix</span> <span class="n">result</span><span class="p">(</span><span class="n">row</span><span class="p">,</span> <span class="n">column</span><span class="p">,</span> <span class="nb">true</span><span class="p">,</span> <span class="n">mod</span><span class="p">);</span> <span class="k">while</span> <span class="p">(</span><span class="n">exponent</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">exponent</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="n">result</span> <span class="o">=</span> <span class="n">result</span> <span class="o">*</span> <span class="n">base</span><span class="p">;</span> <span class="p">}</span> <span class="n">exponent</span> <span class="o">=</span> <span class="n">exponent</span> <span class="o">/</span> <span class="mi">2</span><span class="p">;</span> <span class="n">base</span> <span class="o">=</span> <span class="n">base</span> <span class="o">*</span> <span class="n">base</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="n">result</span><span class="p">;</span> <span class="p">}</span> <span class="n">T</span> <span class="n">trace</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">T</span> <span class="n">result</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">row</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">result</span> <span class="o">+=</span> <span class="n">elements</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">i</span><span class="p">];</span> <span class="p">}</span> <span class="k">return</span> <span class="n">result</span><span class="p">;</span> <span class="p">}</span> <span class="n">T</span> <span class="n">determinant</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// WIP</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="n">Matrix</span> <span class="n">transpose</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">Matrix</span> <span class="n">result</span><span class="p">(</span><span class="n">column</span><span class="p">,</span> <span class="n">row</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">row</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="n">column</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">result</span><span class="p">.</span><span class="n">elements</span><span class="p">[</span><span class="n">j</span><span class="p">][</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">elements</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">];</span> <span class="p">}</span> <span class="p">}</span> <span class="k">return</span> <span class="n">result</span><span class="p">;</span> <span class="p">}</span> <span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o">&lt;</span><span class="kt">size_t</span><span class="p">,</span> <span class="kt">size_t</span><span class="o">&gt;</span> <span class="n">size</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">std</span><span class="o">::</span><span class="n">make_pair</span><span class="p">(</span><span class="n">row</span><span class="p">,</span> <span class="n">column</span><span class="p">);</span> <span class="p">}</span> <span class="k">friend</span> <span class="n">std</span><span class="o">::</span><span class="n">ostream</span><span class="o">&amp;</span> <span class="k">operator</span><span class="o">&lt;&lt;</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">ostream</span><span class="o">&amp;</span> <span class="n">os</span><span class="p">,</span> <span class="k">const</span> <span class="n">Matrix</span> <span class="n">matrix</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">matrix</span><span class="p">.</span><span class="n">row</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="n">matrix</span><span class="p">.</span><span class="n">column</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">os</span> <span class="o">&lt;&lt;</span> <span class="n">matrix</span><span class="p">.</span><span class="n">elements</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span> <span class="o">&lt;&lt;</span> <span class="sc">' '</span><span class="p">;</span> <span class="p">}</span> <span class="n">os</span> <span class="o">&lt;&lt;</span> <span class="sc">'\n'</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="n">os</span><span class="p">;</span> <span class="p">}</span> <span class="p">};</span> <span class="cp">#endif // __MATRIX_HPP__ </span></code></pre></div></div> <h4 id="mainhpp">main.hpp</h4> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;bits/extc++.h&gt;</span><span class="cp"> #include</span> <span class="cpf">"matrix.hpp"</span><span class="cp"> </span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">__gnu_pbds</span><span class="p">;</span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">using</span> <span class="n">ll</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">ull</span> <span class="o">=</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">pll</span> <span class="o">=</span> <span class="n">pair</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;</span><span class="p">;</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="n">ll</span> <span class="n">T</span><span class="p">,</span> <span class="n">N</span><span class="p">,</span> <span class="n">D</span><span class="p">,</span> <span class="n">mod</span> <span class="o">=</span> <span class="mi">1'000'000'007</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">T</span> <span class="o">&gt;&gt;</span> <span class="n">N</span> <span class="o">&gt;&gt;</span> <span class="n">D</span><span class="p">;</span> <span class="n">Matrix</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;</span> <span class="n">combined</span><span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="n">N</span><span class="p">,</span> <span class="nb">false</span><span class="p">,</span> <span class="n">mod</span><span class="p">);</span> <span class="n">Matrix</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;</span> <span class="n">rest</span><span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="n">N</span><span class="p">,</span> <span class="nb">true</span><span class="p">,</span> <span class="n">mod</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">T</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">ll</span> <span class="n">M</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">M</span><span class="p">;</span> <span class="n">Matrix</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;</span> <span class="n">curr</span><span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="n">N</span><span class="p">,</span> <span class="nb">false</span><span class="p">,</span> <span class="n">mod</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="n">M</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">ll</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">a</span> <span class="o">&gt;&gt;</span> <span class="n">b</span> <span class="o">&gt;&gt;</span> <span class="n">c</span><span class="p">;</span> <span class="n">a</span><span class="o">--</span><span class="p">;</span> <span class="n">b</span><span class="o">--</span><span class="p">;</span> <span class="n">curr</span><span class="p">[</span><span class="n">a</span><span class="p">][</span><span class="n">b</span><span class="p">]</span> <span class="o">=</span> <span class="n">c</span> <span class="o">%</span> <span class="n">mod</span><span class="p">;</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">D</span> <span class="o">%</span> <span class="n">T</span> <span class="o">&gt;</span> <span class="n">i</span><span class="p">)</span> <span class="p">{</span> <span class="n">rest</span> <span class="o">=</span> <span class="n">rest</span> <span class="o">*</span> <span class="n">curr</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">D</span> <span class="o">%</span> <span class="n">T</span> <span class="o">==</span> <span class="n">i</span><span class="p">)</span> <span class="p">{</span> <span class="n">combined</span> <span class="o">=</span> <span class="n">rest</span><span class="p">;</span> <span class="p">}</span> <span class="n">combined</span> <span class="o">=</span> <span class="n">combined</span> <span class="o">*</span> <span class="n">curr</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">combined</span><span class="p">.</span><span class="n">power</span><span class="p">(</span><span class="n">D</span> <span class="o">/</span> <span class="n">T</span><span class="p">)</span> <span class="o">*</span> <span class="n">rest</span><span class="p">;</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> </code></pre></div></div> <p>그러자 모든 테스트 케이스를 통과하고 ‘맞았습니다’가 나오는 것을 확인할 수 있었다.</p> <h2 id="마무리">마무리</h2> <p>요즘들어 행렬을 이용한 문제를 푸는 건 즐거운 것 같다. 최근에 수학과 졸업시험 때문에 선형대수학을 복습해서 그런 것일까? 아쉬운 점은 아직까지 CLASS 문제에서 선형대수학을 이용하는 문제가 거의 없다는 것이다! 물론 다른 태그들과 비교해서 알고리즘에 있어 그 중요도가 다소 떨어지기 때문이라는 걸 알지만, 그래도 아쉬운건 어쩔 수 없는 것 같다…</p> <p>그리고 이 문제를 풀어내면서 CLASS 6을 달성하게 되었다!</p> <p><img src="https://static.solved.ac/class/c6.svg" width="50%" height="50%" alt="CLASS 6" /></p> <p>군대 오고 나서 분명 문제는 엄청 많이 푼 것 같은데, CLASS 6 도달하기까지 시간이 꽤나 걸린 것 같다. 게다가 군생활 목표중 하나인 CLASS 6, 7 모두 풀기를 이뤄내기 위해선, 앞으로 CLASS 문제를 5일에 1문제는 풀어야 한다는 무시무시한 결론이 나왔다! 조금 빨리빨리 문제를 풀 필요가 있을 것 같다.</p> <p>그래서 앞으로는 랜덤 마라톤 문제 풀이를 줄이고, CLASS 문제 풀이에 집중하기로 했다. 어짜피 최근 다녀온 신병위로외박 때 노느라 마라톤 다 풀던 기록이 깨지기도 했고, 수학과 졸업 시험 공부도 해야하기 때문에 이런 결정을 내리게 되었다. 마라톤 문제들은 여력이 될 때 할만한 문제들 위주로 풀어보는 걸로 하겠다.</p> <p>내가 만든 행렬 자료구조는 내 레포지토리<sup><a href="#footnote_2">2</a></sup>에서 확인할 수 있다.</p> <p>오늘의 PS는 여기까지!</p> <hr /> <p><a name="footnote_1">1</a>: <a href="https://www.acmicpc.net/problem/17401">https://www.acmicpc.net/problem/17401</a><br /> <a name="footnote_2">2</a>: <a href="https://github.com/ChoiCube84/baekjoon-solutions/blob/main/C%2B%2B/custom_data_structures/matrix.hpp">https://github.com/ChoiCube84/baekjoon-solutions/blob/main/C%2B%2B/custom_data_structures/matrix.hpp</a></p> Sun, 11 Aug 2024 23:59:00 +0900 https://choicube84.github.io/study/2024/08/11/baekjoon_17401.html https://choicube84.github.io/study/2024/08/11/baekjoon_17401.html problem_solving Study 백준 16287번 <h1 id="백준-16287번">백준 16287번</h1> <p>오늘 풀어본 문제는 백준의 16287번 문제<sup><a href="#footnote_1">1</a></sup>이다. 문제 풀이에 사용한 언어는 C++ 이다.</p> <h2 id="solvedac-기준-class">solved.ac 기준 CLASS</h2> <p><img src="https://static.solved.ac/class/c6.svg" width="50%" height="50%" alt="CLASS 6" /></p> <h2 id="문제-정보">문제 정보</h2> <p>이 문제의 내용과 조건은 다음과 같다.</p> <h3 id="문제">문제</h3> <p>국제대학소포센터(ICPC: International Collegiate Parcel Center)는 전세계 대학생들을 대상으로 소포 무료 배송 이벤트를 진행하고 있다. 무료 배송 조건은 보낼 소포가 물품 $4$ 개로 구성되어야 하며 이들 물품의 무게 합이 정확히 정해진 정수 무게 $w$ 그램이어야 한다는 것이다.</p> <p>부산대학교에 있는 찬수는 영국 왕립대학에 있는 수환에게 보낼 물품이 매우 많이 있는데, 각 물품의 무게(모두 정수 그램)는 모두 다르다. 이 이벤트는 한시적으로 진행되는 이벤트이기 때문에 찬수는 자신이 보낼 물품 중에서 이 조건을 만족하는 물품 $4$ 개가 있는지 가능하면 빨리 알아내고 싶다. 다시 말해서 서로 다른 $n$ $(n \le 4)$ 개의 정수로 이루어진 집합 $A$ 에서 $4$ 개의 원소만 꺼내어 만든 부분집합 $B$ $(\vert B \vert = 4)$ 가 $\sum_{b \in B} b = w$ 조건을 만족하는지 판단하려고 한다.</p> <p>주어진 $w$ 와 $A$ 에 대해서, 위 조건을 만족하는 부분집합 $B$ 가 존재하면 YES를, 아니면 NO를 출력하는 프로그램을 작성하시오.</p> <h3 id="입력">입력</h3> <p>입력은 표준입력을 사용한다. 입력의 첫 줄에는 무게 $w$ $(10 \le w \le 799,994)$ 와 $A$ 의 원소 개수 $n$ $(4 \le n \le 5,000)$ 이 공백으로 분리되어 주어진다. 다음 줄에는 $A$ 의 원소인 $n$ 개의 정수 $a_i \in A$ $(1 \le i \le n)$ 가 공백으로 분리되어 주어진다. 각 원소 $a_i$ 는 $1$ 이상 $200,000$ 이하이다 $(1 \le a_i \le 200,000)$.</p> <h3 id="출력">출력</h3> <p>출력은 표준출력을 사용한다. 문제의 조건에 따라 YES나 NO를 한 줄에 출력한다.</p> <h2 id="풀이과정">풀이과정</h2> <h3 id="1번째-시도">1번째 시도</h3> <p>문제를 보고 4개의 물품의 무게의 합을 조사하기 위해, 2개씩 묶은 것들끼리 비교하면 될 것 같다는 생각이 들었다. 이를 위해 MITM 방식을 이용하기로 하였고, 다른 물품들의 조합으로 같은 무게가 나올 수 있기 때문에 <code class="language-plaintext highlighter-rouge">std::unordered_multimap</code> 을 활용하기로 하였다.</p> <p>코드는 다음과 같이 작성하였다.</p> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;bits/stdc++.h&gt;</span><span class="cp"> #include</span> <span class="cpf">&lt;unordered_map&gt;</span><span class="cp"> </span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">using</span> <span class="n">ll</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">ull</span> <span class="o">=</span> <span class="kt">unsigned</span> <span class="n">ll</span><span class="p">;</span> <span class="k">using</span> <span class="n">pii</span> <span class="o">=</span> <span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;</span><span class="p">;</span> <span class="k">using</span> <span class="n">pll</span> <span class="o">=</span> <span class="n">pair</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;</span><span class="p">;</span> <span class="kt">bool</span> <span class="nf">pairCollide</span><span class="p">(</span><span class="k">const</span> <span class="n">pii</span><span class="o">&amp;</span> <span class="n">A</span><span class="p">,</span> <span class="k">const</span> <span class="n">pii</span><span class="o">&amp;</span> <span class="n">B</span><span class="p">);</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="kt">int</span> <span class="n">w</span><span class="p">,</span> <span class="n">A</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">w</span> <span class="o">&gt;&gt;</span> <span class="n">A</span><span class="p">;</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">items</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">A</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">items</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="p">}</span> <span class="n">unordered_multimap</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="n">pii</span><span class="o">&gt;</span> <span class="n">umap</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">A</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">j</span><span class="o">=</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="n">A</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">umap</span><span class="p">.</span><span class="n">insert</span><span class="p">({</span><span class="n">items</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="n">items</span><span class="p">[</span><span class="n">j</span><span class="p">],</span> <span class="n">make_pair</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">)});</span> <span class="p">}</span> <span class="p">}</span> <span class="kt">bool</span> <span class="n">found</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">A</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">j</span><span class="o">=</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="n">A</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">auto</span> <span class="n">range</span> <span class="o">=</span> <span class="n">umap</span><span class="p">.</span><span class="n">equal_range</span><span class="p">(</span><span class="n">w</span> <span class="o">-</span> <span class="p">(</span><span class="n">items</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="n">items</span><span class="p">[</span><span class="n">j</span><span class="p">]));</span> <span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="n">it</span> <span class="o">=</span> <span class="n">range</span><span class="p">.</span><span class="n">first</span><span class="p">;</span> <span class="n">it</span> <span class="o">!=</span> <span class="n">range</span><span class="p">.</span><span class="n">second</span><span class="p">;</span> <span class="o">++</span><span class="n">it</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">pairCollide</span><span class="p">(</span><span class="n">make_pair</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">),</span> <span class="n">it</span><span class="o">-&gt;</span><span class="n">second</span><span class="p">))</span> <span class="p">{</span> <span class="n">found</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span> <span class="k">break</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">found</span><span class="p">)</span> <span class="k">break</span><span class="p">;</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">found</span><span class="p">)</span> <span class="k">break</span><span class="p">;</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">found</span><span class="p">)</span> <span class="p">{</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"YES"</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"NO"</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="kt">bool</span> <span class="n">pairCollide</span><span class="p">(</span><span class="k">const</span> <span class="n">pii</span><span class="o">&amp;</span> <span class="n">A</span><span class="p">,</span> <span class="k">const</span> <span class="n">pii</span><span class="o">&amp;</span> <span class="n">B</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="n">A</span><span class="p">.</span><span class="n">first</span> <span class="o">==</span> <span class="n">B</span><span class="p">.</span><span class="n">first</span> <span class="o">||</span> <span class="n">A</span><span class="p">.</span><span class="n">first</span> <span class="o">==</span> <span class="n">B</span><span class="p">.</span><span class="n">second</span> <span class="o">||</span> <span class="n">A</span><span class="p">.</span><span class="n">second</span><span class="o">==</span> <span class="n">B</span><span class="p">.</span><span class="n">first</span> <span class="o">||</span> <span class="n">A</span><span class="p">.</span><span class="n">second</span> <span class="o">==</span> <span class="n">B</span><span class="p">.</span><span class="n">second</span><span class="p">;</span> <span class="p">}</span> </code></pre></div></div> <p>실행 결과 ‘메모리 초과’ 가 떴다.</p> <h3 id="2번째-시도">2번째 시도</h3> <p>메모리 초과는 역시 <code class="language-plaintext highlighter-rouge">unordered map</code> 의 사용으로 인한 것이라고 생각되었다. 당시에 이 문제를 더 붙들만한 시간이 없어 나중에 다시 풀어보기로 하였고, 문제를 푸는 방식을 바꿔보기로 하였다.</p> <p>전체 물품들을 두 그룹으로 나누고, 각 그룹에서 2개씩 골라 무게를 저장하고, 나머지 그룹에서 2개씩 골라서 나온 무게 중 첫 번째 그룹에서 나온 무게와 합쳐 목표 무게가 나올 수 있는지 확인하는 방식으로 해결해보기로 했다.</p> <p>코드는 다음과 같이 새로 작성하였다.</p> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;bits/extc++.h&gt;</span><span class="cp"> </span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">__gnu_pbds</span><span class="p">;</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="kt">int</span> <span class="n">w</span><span class="p">,</span> <span class="n">A</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">w</span> <span class="o">&gt;&gt;</span> <span class="n">A</span><span class="p">;</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">items</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">A</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">items</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="p">}</span> <span class="n">gp_hash_table</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;</span> <span class="n">table</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="p">(</span><span class="n">A</span><span class="o">/</span><span class="mi">2</span><span class="p">);</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">j</span><span class="o">=</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="p">(</span><span class="n">A</span><span class="o">/</span><span class="mi">2</span><span class="p">);</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="kt">int</span> <span class="n">sum</span> <span class="o">=</span> <span class="n">items</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="n">items</span><span class="p">[</span><span class="n">j</span><span class="p">];</span> <span class="k">if</span> <span class="p">(</span><span class="n">table</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">sum</span><span class="p">)</span> <span class="o">==</span> <span class="n">table</span><span class="p">.</span><span class="n">end</span><span class="p">())</span> <span class="p">{</span> <span class="n">table</span><span class="p">[</span><span class="n">sum</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">table</span><span class="p">[</span><span class="n">sum</span><span class="p">]</span><span class="o">++</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="kt">bool</span> <span class="n">found</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="p">(</span><span class="n">A</span><span class="o">/</span><span class="mi">2</span><span class="p">);</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">A</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">j</span><span class="o">=</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="n">A</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="kt">int</span> <span class="n">sum</span> <span class="o">=</span> <span class="n">items</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="n">items</span><span class="p">[</span><span class="n">j</span><span class="p">];</span> <span class="k">if</span> <span class="p">(</span><span class="n">table</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">w</span> <span class="o">-</span> <span class="n">sum</span><span class="p">)</span> <span class="o">!=</span> <span class="n">table</span><span class="p">.</span><span class="n">end</span><span class="p">())</span> <span class="p">{</span> <span class="n">found</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span> <span class="k">break</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">found</span><span class="p">)</span> <span class="k">break</span><span class="p">;</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">found</span><span class="p">)</span> <span class="p">{</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"YES"</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"NO"</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> </code></pre></div></div> <p>실행 결과 ‘틀렸습니다’ 가 떴다.</p> <h3 id="3번째-시도">3번째 시도</h3> <p>문제 풀이 방식에는 틀린 것이 없다고 생각했고, 오버플로우 문제인 것 같아 <code class="language-plaintext highlighter-rouge">int</code> 대신 <code class="language-plaintext highlighter-rouge">long long int</code> 형을 사용하기로 하였다.</p> <p>코드는 다음과 같이 수정하였다.</p> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;bits/extc++.h&gt;</span><span class="cp"> </span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">__gnu_pbds</span><span class="p">;</span> <span class="k">using</span> <span class="n">ll</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">ll</span> <span class="n">w</span><span class="p">,</span> <span class="n">A</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">w</span> <span class="o">&gt;&gt;</span> <span class="n">A</span><span class="p">;</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;</span> <span class="n">items</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">A</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">items</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="p">}</span> <span class="n">gp_hash_table</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;</span> <span class="n">table</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="p">(</span><span class="n">A</span><span class="o">/</span><span class="mi">2</span><span class="p">);</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">j</span><span class="o">=</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="p">(</span><span class="n">A</span><span class="o">/</span><span class="mi">2</span><span class="p">);</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">ll</span> <span class="n">sum</span> <span class="o">=</span> <span class="n">items</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="n">items</span><span class="p">[</span><span class="n">j</span><span class="p">];</span> <span class="k">if</span> <span class="p">(</span><span class="n">table</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">sum</span><span class="p">)</span> <span class="o">==</span> <span class="n">table</span><span class="p">.</span><span class="n">end</span><span class="p">())</span> <span class="p">{</span> <span class="n">table</span><span class="p">[</span><span class="n">sum</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">table</span><span class="p">[</span><span class="n">sum</span><span class="p">]</span><span class="o">++</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="kt">bool</span> <span class="n">found</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="p">(</span><span class="n">A</span><span class="o">/</span><span class="mi">2</span><span class="p">);</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">A</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">j</span><span class="o">=</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="n">A</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">ll</span> <span class="n">sum</span> <span class="o">=</span> <span class="n">items</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="n">items</span><span class="p">[</span><span class="n">j</span><span class="p">];</span> <span class="k">if</span> <span class="p">(</span><span class="n">table</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">w</span> <span class="o">-</span> <span class="n">sum</span><span class="p">)</span> <span class="o">!=</span> <span class="n">table</span><span class="p">.</span><span class="n">end</span><span class="p">())</span> <span class="p">{</span> <span class="n">found</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span> <span class="k">break</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">found</span><span class="p">)</span> <span class="k">break</span><span class="p">;</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">found</span><span class="p">)</span> <span class="p">{</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"YES"</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"NO"</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> </code></pre></div></div> <p>실행 결과 ‘틀렸습니다’ 가 떴다.</p> <h3 id="4번째-시도">4번째 시도</h3> <p>지금와서 보면, 제대로 고려하지 않은 사항이 너무나도 많은 풀이법이지만, 당시에는 이상한 점을 느끼지 못했고 이 문제의 풀이를 중단했었다. 2, 3번째 시도의 방식의 문제점은, 유일한 방법이 한 그룹에서 4개를 고르거나, 한 그룹에서 3개와 나머지 그룹에서 1개를 고르는 방식으로 구성되는 경우를 제대로 처리할 수 없다는 점이었다.</p> <p>결국 이 문제를 풀어내기 위해 다른 사람들이 이용한 방식을 찾아보았는데, 내가 문제에서 한 가지 생각하지 못한 부분이 있었다. 그것은 모든 물품의 무게가 다르다는 것이었다. 이 점을 이용하면 첫 번째 풀이에서 사용한 방식을 이용할 수 있었다. 단, 가능한 모든 조합을 저장하는 것이 아닌, 딱 하나만 저장해도 되는 것이었다!</p> <p>코드는 다음과 같이 새로 작성하였다.</p> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;bits/extc++.h&gt;</span><span class="cp"> </span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">__gnu_pbds</span><span class="p">;</span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">using</span> <span class="n">ll</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">ull</span> <span class="o">=</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">pll</span> <span class="o">=</span> <span class="n">pair</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;</span><span class="p">;</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="n">ll</span> <span class="n">w</span><span class="p">,</span> <span class="n">n</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">w</span> <span class="o">&gt;&gt;</span> <span class="n">n</span><span class="p">;</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;</span> <span class="n">A</span><span class="p">(</span><span class="n">n</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="p">}</span> <span class="n">gp_hash_table</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">pll</span><span class="o">&gt;</span> <span class="n">table</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">j</span><span class="o">=</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">ll</span> <span class="n">sum</span> <span class="o">=</span> <span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="n">A</span><span class="p">[</span><span class="n">j</span><span class="p">];</span> <span class="k">if</span> <span class="p">(</span><span class="n">table</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">sum</span><span class="p">)</span> <span class="o">==</span> <span class="n">table</span><span class="p">.</span><span class="n">end</span><span class="p">())</span> <span class="p">{</span> <span class="n">table</span><span class="p">[</span><span class="n">sum</span><span class="p">]</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">j</span><span class="o">=</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">ll</span> <span class="n">sum</span> <span class="o">=</span> <span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="n">A</span><span class="p">[</span><span class="n">j</span><span class="p">];</span> <span class="k">if</span> <span class="p">(</span><span class="n">table</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">w</span> <span class="o">-</span> <span class="n">sum</span><span class="p">)</span> <span class="o">!=</span> <span class="n">table</span><span class="p">.</span><span class="n">end</span><span class="p">())</span> <span class="p">{</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"YES"</span><span class="p">;</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"NO"</span><span class="p">;</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> </code></pre></div></div> <p>실행 결과 ‘틀렸습니다’ 가 떴다.</p> <h3 id="5번째-시도">5번째 시도</h3> <p>틀린 원인으로 조합을 검사하는 과정에서, 물품이 중복되었는지 확인하는 코드를 작성하는 것을 깜빡했다는 것을 금방 발견할 수 있었다.</p> <p>코드는 다음과 같이 수정하였다.</p> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;bits/extc++.h&gt;</span><span class="cp"> </span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">__gnu_pbds</span><span class="p">;</span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">using</span> <span class="n">ll</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">ull</span> <span class="o">=</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">pll</span> <span class="o">=</span> <span class="n">pair</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;</span><span class="p">;</span> <span class="kt">bool</span> <span class="nf">pairCollide</span><span class="p">(</span><span class="k">const</span> <span class="n">pll</span><span class="o">&amp;</span> <span class="n">a</span><span class="p">,</span> <span class="k">const</span> <span class="n">pll</span><span class="o">&amp;</span> <span class="n">b</span><span class="p">);</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="n">ll</span> <span class="n">w</span><span class="p">,</span> <span class="n">n</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">w</span> <span class="o">&gt;&gt;</span> <span class="n">n</span><span class="p">;</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;</span> <span class="n">A</span><span class="p">(</span><span class="n">n</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="p">}</span> <span class="n">gp_hash_table</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">pll</span><span class="o">&gt;</span> <span class="n">table</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">j</span><span class="o">=</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">ll</span> <span class="n">sum</span> <span class="o">=</span> <span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="n">A</span><span class="p">[</span><span class="n">j</span><span class="p">];</span> <span class="k">if</span> <span class="p">(</span><span class="n">table</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">sum</span><span class="p">)</span> <span class="o">==</span> <span class="n">table</span><span class="p">.</span><span class="n">end</span><span class="p">())</span> <span class="p">{</span> <span class="n">table</span><span class="p">[</span><span class="n">sum</span><span class="p">]</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">j</span><span class="o">=</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">ll</span> <span class="n">sum</span> <span class="o">=</span> <span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="n">A</span><span class="p">[</span><span class="n">j</span><span class="p">];</span> <span class="k">if</span> <span class="p">(</span><span class="n">table</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">w</span> <span class="o">-</span> <span class="n">sum</span><span class="p">)</span> <span class="o">!=</span> <span class="n">table</span><span class="p">.</span><span class="n">end</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">pairCollide</span><span class="p">(</span><span class="n">table</span><span class="p">[</span><span class="n">w</span> <span class="o">-</span> <span class="n">sum</span><span class="p">],</span> <span class="n">make_pair</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">)))</span> <span class="p">{</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"YES"</span><span class="p">;</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"NO"</span><span class="p">;</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="kt">bool</span> <span class="n">pairCollide</span><span class="p">(</span><span class="k">const</span> <span class="n">pll</span><span class="o">&amp;</span> <span class="n">a</span><span class="p">,</span> <span class="k">const</span> <span class="n">pll</span><span class="o">&amp;</span> <span class="n">b</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">a</span><span class="p">.</span><span class="n">first</span> <span class="o">==</span> <span class="n">b</span><span class="p">.</span><span class="n">first</span> <span class="o">||</span> <span class="n">a</span><span class="p">.</span><span class="n">first</span> <span class="o">==</span> <span class="n">b</span><span class="p">.</span><span class="n">second</span> <span class="o">||</span> <span class="n">a</span><span class="p">.</span><span class="n">second</span> <span class="o">==</span> <span class="n">b</span><span class="p">.</span><span class="n">first</span> <span class="o">||</span> <span class="n">a</span><span class="p">.</span><span class="n">second</span> <span class="o">==</span> <span class="n">b</span><span class="p">.</span><span class="n">second</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nb">true</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="nb">false</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>실행 결과 ‘시간 초과’ 가 떴다.</p> <h3 id="6번째-시도">6번째 시도</h3> <p>시간 초과의 원인으로, 알고리즘이 문제가 있는 것 같지는 않았다. 그냥 <code class="language-plaintext highlighter-rouge">gp_hash_table</code> 자체가 느려서 발생하는 문제일 것이라고 생각했다. <del>그렇다면 대체 <code class="language-plaintext highlighter-rouge">std::unordered_map</code>은 얼마나 느리다는 것인가…</del></p> <p>그래서 해시 테이블 대신 <code class="language-plaintext highlighter-rouge">std::vector</code> 를 활용하여 무게들을 저장하기로 하였다.</p> <p>코드는 다음과 같이 작성하였다.</p> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;bits/extc++.h&gt;</span><span class="cp"> </span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">__gnu_pbds</span><span class="p">;</span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">using</span> <span class="n">ll</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">ull</span> <span class="o">=</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">pll</span> <span class="o">=</span> <span class="n">pair</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;</span><span class="p">;</span> <span class="kt">bool</span> <span class="nf">pairCollide</span><span class="p">(</span><span class="k">const</span> <span class="n">pll</span><span class="o">&amp;</span> <span class="n">a</span><span class="p">,</span> <span class="k">const</span> <span class="n">pll</span><span class="o">&amp;</span> <span class="n">b</span><span class="p">);</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="n">ll</span> <span class="n">w</span><span class="p">,</span> <span class="n">n</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">w</span> <span class="o">&gt;&gt;</span> <span class="n">n</span><span class="p">;</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;</span> <span class="n">A</span><span class="p">(</span><span class="n">n</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="p">}</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">pll</span><span class="o">&gt;</span> <span class="n">combinations</span><span class="p">(</span><span class="mi">400001</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="mi">400001</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">combinations</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">first</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span> <span class="p">}</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">j</span><span class="o">=</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">combinations</span><span class="p">[</span><span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="n">A</span><span class="p">[</span><span class="n">j</span><span class="p">]]</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">j</span><span class="o">=</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">ll</span> <span class="n">sum</span> <span class="o">=</span> <span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="n">A</span><span class="p">[</span><span class="n">j</span><span class="p">];</span> <span class="k">if</span> <span class="p">(</span><span class="n">sum</span> <span class="o">&lt;=</span> <span class="n">w</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="p">(</span><span class="n">combinations</span><span class="p">[</span><span class="n">w</span> <span class="o">-</span> <span class="n">sum</span><span class="p">].</span><span class="n">first</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">pairCollide</span><span class="p">(</span><span class="n">combinations</span><span class="p">[</span><span class="n">w</span> <span class="o">-</span> <span class="n">sum</span><span class="p">],</span> <span class="n">make_pair</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">)))</span> <span class="p">{</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"YES"</span><span class="p">;</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"NO"</span><span class="p">;</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="kt">bool</span> <span class="n">pairCollide</span><span class="p">(</span><span class="k">const</span> <span class="n">pll</span><span class="o">&amp;</span> <span class="n">a</span><span class="p">,</span> <span class="k">const</span> <span class="n">pll</span><span class="o">&amp;</span> <span class="n">b</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">a</span><span class="p">.</span><span class="n">first</span> <span class="o">==</span> <span class="n">b</span><span class="p">.</span><span class="n">first</span> <span class="o">||</span> <span class="n">a</span><span class="p">.</span><span class="n">first</span> <span class="o">==</span> <span class="n">b</span><span class="p">.</span><span class="n">second</span> <span class="o">||</span> <span class="n">a</span><span class="p">.</span><span class="n">second</span> <span class="o">==</span> <span class="n">b</span><span class="p">.</span><span class="n">first</span> <span class="o">||</span> <span class="n">a</span><span class="p">.</span><span class="n">second</span> <span class="o">==</span> <span class="n">b</span><span class="p">.</span><span class="n">second</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nb">true</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="nb">false</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>실행 결과 ‘런타임 에러 (OutOfBounds)’ 가 떴다.</p> <h3 id="7번째-시도">7번째 시도</h3> <p>수정 과정에서 코드 복사를 잘못해서 컴파일 정상적으로 되도록 고치기 이전의 코드를 붙여넣기 해버렸다. 당연하게도 실행 결과 ‘컴파일 에러’ 가 떴다. <del>어이 없게 글 분량만 늘어났다…</del></p> <h3 id="8번째-시도">8번째 시도</h3> <p>6번째 시도에서 발생한 런타임 에러는 OutOfBounds 였다. 그래서 뭔가 <code class="language-plaintext highlighter-rouge">std::vector</code> 에서 접근 오류가 발생한 것 같아 그냥 저장 용량을 늘려줘봤다.</p> <p>코드는 다음과 같이 수정하였다.</p> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;bits/extc++.h&gt;</span><span class="cp"> </span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">__gnu_pbds</span><span class="p">;</span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">using</span> <span class="n">ll</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">ull</span> <span class="o">=</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="kt">long</span> <span class="kt">int</span><span class="p">;</span> <span class="k">using</span> <span class="n">pll</span> <span class="o">=</span> <span class="n">pair</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;</span><span class="p">;</span> <span class="kt">bool</span> <span class="nf">pairCollide</span><span class="p">(</span><span class="k">const</span> <span class="n">pll</span><span class="o">&amp;</span> <span class="n">a</span><span class="p">,</span> <span class="k">const</span> <span class="n">pll</span><span class="o">&amp;</span> <span class="n">b</span><span class="p">);</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="n">ll</span> <span class="n">w</span><span class="p">,</span> <span class="n">n</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">w</span> <span class="o">&gt;&gt;</span> <span class="n">n</span><span class="p">;</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;</span> <span class="n">A</span><span class="p">(</span><span class="n">n</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="p">}</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">pll</span><span class="o">&gt;</span> <span class="n">combinations</span><span class="p">(</span><span class="mi">800001</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="mi">800001</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">combinations</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">first</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span> <span class="p">}</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">j</span><span class="o">=</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">combinations</span><span class="p">[</span><span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="n">A</span><span class="p">[</span><span class="n">j</span><span class="p">]]</span> <span class="o">=</span> <span class="n">make_pair</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="n">ll</span> <span class="n">j</span><span class="o">=</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">ll</span> <span class="n">sum</span> <span class="o">=</span> <span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="n">A</span><span class="p">[</span><span class="n">j</span><span class="p">];</span> <span class="k">if</span> <span class="p">(</span><span class="n">sum</span> <span class="o">&lt;=</span> <span class="n">w</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="p">(</span><span class="n">combinations</span><span class="p">[</span><span class="n">w</span> <span class="o">-</span> <span class="n">sum</span><span class="p">].</span><span class="n">first</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">pairCollide</span><span class="p">(</span><span class="n">combinations</span><span class="p">[</span><span class="n">w</span> <span class="o">-</span> <span class="n">sum</span><span class="p">],</span> <span class="n">make_pair</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">)))</span> <span class="p">{</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"YES"</span><span class="p">;</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"NO"</span><span class="p">;</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="kt">bool</span> <span class="n">pairCollide</span><span class="p">(</span><span class="k">const</span> <span class="n">pll</span><span class="o">&amp;</span> <span class="n">a</span><span class="p">,</span> <span class="k">const</span> <span class="n">pll</span><span class="o">&amp;</span> <span class="n">b</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">a</span><span class="p">.</span><span class="n">first</span> <span class="o">==</span> <span class="n">b</span><span class="p">.</span><span class="n">first</span> <span class="o">||</span> <span class="n">a</span><span class="p">.</span><span class="n">first</span> <span class="o">==</span> <span class="n">b</span><span class="p">.</span><span class="n">second</span> <span class="o">||</span> <span class="n">a</span><span class="p">.</span><span class="n">second</span> <span class="o">==</span> <span class="n">b</span><span class="p">.</span><span class="n">first</span> <span class="o">||</span> <span class="n">a</span><span class="p">.</span><span class="n">second</span> <span class="o">==</span> <span class="n">b</span><span class="p">.</span><span class="n">second</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nb">true</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="nb">false</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>그러자 모든 테스트 케이스를 통과하고 ‘맞았습니다’가 나오는 것을 확인할 수 있었다.</p> <h2 id="마무리">마무리</h2> <p>백준 1006번 (습격자 초라기) 급은 아니지만, 이 문제도 풀어내는데 나름 오래걸린 문제였고, CLASS 6 문제를 모두 풀어내기 위해서는 반드시 거쳐야하는 관문이었기 때문에, 풀어내고 나서 굉장히 홀가분한 기분이 들었다.</p> <p>이번 문제에서 충격적이었던 부분은, 물품의 무게가 모두 달라 가능한 여러 조합 중 하나만 저장해도 된다는 것이었다. 사실 이걸 떠올리는 것과 MITM 을 이용하는 것이 이 문제의 핵심이었던 것 같은데, MITM 은 쉽게 떠올렸어도 하나만 저장해도 된다는 것은 전혀 상상도 못했기 때문이다. 첫 번째 시도에서 <code class="language-plaintext highlighter-rouge">std::unordered_map</code> 이 아닌 <code class="language-plaintext highlighter-rouge">std::unordered_multimap</code> 을 이용한 것도 그런 이유였다.</p> <p>앞으로는 이런 식으로 핵심 아이디어들을 끄집어낼 수 있는 능력이 중요할 것 같은데, 아직 준비가 잘 안된 것 같아 걱정스러워지기 시작했다.</p> <p>오늘의 PS는 여기까지!</p> <hr /> <p><a name="footnote_1">1</a>: <a href="https://www.acmicpc.net/problem/16287">https://www.acmicpc.net/problem/16287</a></p> Fri, 09 Aug 2024 23:59:00 +0900 https://choicube84.github.io/study/2024/08/09/baekjoon_16287.html https://choicube84.github.io/study/2024/08/09/baekjoon_16287.html problem_solving Study