<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>음준희 블로그</title>
    <link>https://joonhee305.tistory.com/</link>
    <description>개인적으로 한 공부들 정리하는 곳</description>
    <language>ko</language>
    <pubDate>Sat, 4 Apr 2026 19:10:36 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>joonhee305</managingEditor>
    <item>
      <title>동일 호스트에서 컨테이너 간 통신오류</title>
      <link>https://joonhee305.tistory.com/72</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;외부에서 도메인으로 요청을 받고, 그 요청을 도메인 이름에 따라서 서비스들로 매핑해주는 A Caddy&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요청을 받으면 정적 파일을 보내주는 B Caddy&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 A Caddy에서 요청을 받으면 B Caddy로 요청을 넘겨준 뒤 요청한 웹 파일을 받아오는 구조를 생각했다.&lt;br /&gt;&lt;br /&gt;A Caddy와 B Caddy 모두 docker-compose를 통해 관리하였으며, A Caddy의 컨테이너는 80포트, 443포트를 수신하고, B Caddy의 컨테이너는 X 포트를 받아서 내부의 Y포트로 포워딩 해주는 역할을 맡았다.&lt;br /&gt;&lt;br /&gt;기존 A Caddy는 1번서버, B Caddy는 2번서버, 즉 분리된 서버에서 동작하였으며, 잘 동작하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 A Caddy, B Caddy를 모두 1번 서버에서(즉 동일한 호스트에서) 실행하다보니 문제가 발생하였다.&lt;br /&gt;&lt;br /&gt;처음 만난 문제는 Hiarpin Nat 문제였다. 요청이 자기 자신에게 돌아오는것이며, 도커는 이를 보안상 위협으로 취급하여 차단한다고 한다. 따라서 나는 동일한 네트워크를 사용할 수 있도록 A caddy의 docker compose에 아래와 같은 내용을 추가하였다.&lt;/p&gt;
&lt;pre id=&quot;code_1749562645456&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;networks:
  service-net-name:
    external: true # 기존 네트워크 재사용&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;external을 사용하면 기존에 생성된 네트워크를 재사용 할 수 있다고 한다. 따라서 기존 서비스에서 생성된 네트워크에 연결하여 A Caddy가 서비스에 직접 요청을 할 수 있도록 하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 A Caddy에서 요청을 받으면 B Caddy 컨테이너의 X 포트로 넘겨 동작을 시키고 싶었다. 하지만 찾아보니 이는 표준이 아니고, 보안상으로 불필요한 포트를 더 열어 좋지 않다고 한다.&lt;br /&gt;&lt;br /&gt;따라서 기존 B Caddy에서 열었던 X to Y 포트 포워딩을 삭제하고 A Caddy에서 Y포트로 직접 접근하도록 하여 해결하였다.&lt;/p&gt;</description>
      <category>과제 및 프로젝트/메이플스토리</category>
      <author>joonhee305</author>
      <guid isPermaLink="true">https://joonhee305.tistory.com/72</guid>
      <comments>https://joonhee305.tistory.com/72#entry72comment</comments>
      <pubDate>Tue, 10 Jun 2025 22:38:19 +0900</pubDate>
    </item>
    <item>
      <title>[메길드] 메길드 서비스 개발 기록</title>
      <link>https://joonhee305.tistory.com/71</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://maplegd.com&quot;&gt;https://maplegd.com&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1748271744357&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;메길드 - 메이플 길드 관리 서비스&quot; data-og-description=&quot;메이플스토리 길드 정보를 쉽게 검색하고 관리하세요.&quot; data-og-host=&quot;maplegd.com&quot; data-og-source-url=&quot;https://maplegd.com&quot; data-og-url=&quot;https://maplegd.com/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://maplegd.com&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://maplegd.com&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;메길드 - 메이플 길드 관리 서비스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;메이플스토리 길드 정보를 쉽게 검색하고 관리하세요.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;maplegd.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메길드 서비스를 배포하는데 까지 있었던 일을 기록한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우연히 길드장의 길드 관리의 애로사항을 듣게되어 개발을 시작하게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본.부캐를 모두 관리하다 보니, 하나하나 찾는게 귀찮고 어렵다는 것이였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 한눈에 쉽게 볼 수 있도록 하는 서비스를 생각했다. 겸사겸사 부캐 길드도 함께 되도록 말이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 모든 데이터는 넥슨 OpenAPI를 사용하여 질의한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.&amp;nbsp; 로직 구상&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 서비스를 구현하기 위해서는 반드시 필요한 정보들이 있다. 바로 길드원 리스트와 특정 캐릭터의 본캐 정보다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;길드원 리스트는 길드 정보 API를 통해 가져올 수 있지만, 본캐 정보가 까다로웠다. 계정 내 모든 캐릭터를 확인하기 위해선 해당 계정에서 발급받은 API키가 필요하지만, 길드원한테 일일히 API 키를 요구할 수는 없지 않은가...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 랭킹 정보에서 유니온 랭킹 API를 사용했다. 유니온 랭킹 API에 나오는 대표 캐릭터는 서버 내 레벨이 가장 높은 캐릭터로 나오는 것 같았다. 이를 본캐의 선정 기준으로 하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 길드원 리스트 - 길드 식별자 조회 후 식별자를 통한 기본 정보 조회&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 본캐 정보 - 유니온 랭킹 조회를 통한 본캐 추출&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 개발 환경 구축&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인적으로 사용중인 미니 PC가 있었다. N100을 사용한 저렴한 10만원정도 하는 PC인데 클라우드 대신 개인용 서버로 굉장히 쓸만하다. Ubuntu 24.04였나.. 무튼 우분투 최신버전을 설치했었고, 구체적인 서버 구축 방법은 추후 따로 업로드 할 예정이다. 해당 서버에서 개발 및 배포를 진행한다. 로컬, 서버에 각각 개발 환경을 만들기는 좀 귀찮아서 vscode remote를 활용해서 서버에서 직접 개발을 진행했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 개발 과정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 본인은 대부분 프로젝트를 하면 백엔드를 주로 맡았기 때문에, 프론트 쪽에는 전혀 문외한이였다. 기껏해야 html 조금 써본 정도..? 요새 AI가 기똥차게 프론트엔드 코드를 잘 짜준다니 믿어보도록 하겠다. 모델은 gemini 2.5 exp를 사용했다. 무료버전인데 성능이 상당하더라.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) UI&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;863&quot; data-origin-height=&quot;494&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ezUbwr/btsOmjiE1cb/33qHfbqdDROW6cybb3Te0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ezUbwr/btsOmjiE1cb/33qHfbqdDROW6cybb3Te0k/img.png&quot; data-alt=&quot;대충 ppt로 네모네모 하게 디자인 후 '해줘' 시전&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ezUbwr/btsOmjiE1cb/33qHfbqdDROW6cybb3Te0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FezUbwr%2FbtsOmjiE1cb%2F33qHfbqdDROW6cybb3Te0k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;863&quot; height=&quot;494&quot; data-origin-width=&quot;863&quot; data-origin-height=&quot;494&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;대충 ppt로 네모네모 하게 디자인 후 '해줘' 시전&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대충 이런 느낌으로 간단한 디자인 이미지, 그리고 필요로 하는 기능을 명시해두면 알아서 코드를 짜준다. Wa! 대부분의 코드는 이런식으로 짯었고, 특정 요소에서 기능을 필요로 할 때, 이미지에 번호를 추가하고, 그 번호에 대한 설명을 적어주면 좀 더 잘 이해하더라. 프론트의 대부분의 기능은 AI를 통해 해결했다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 길드 본/부캐 정보 조회 API 구현&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 프론트는 AI로 대부분 해결했다. 본/부캐 API에서 리턴하는 데이터타입만 명시해주면 그거에 맞춰서 알아서 캐릭터 카드, 정렬 등을 다 해주는데 얼마나 좋은가. 내가 할 일은 명시해둔 응답 데이터 타입에 맞게 Nexon Open API의 데이터들을 잘 조합하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 길드 내 캐릭터 조회 - 길드 정보 조회 API에서 확인 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 캐릭터 본캐 정보 - 특정 캐릭터의 OCID 조회 후 OCID기반으로 유니온 랭킹을 검색했을 때 가장 높은 레벨의 캐릭터가 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 가지를 조합해서 본/부캐 정보를 프론트에 전달해줬다. Wa!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;후기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자세히 적고싶었는데 막상 적다보니 너무 단순해서 적을말이 없었다. 혹시나 궁금한게 있다면 댓글로 남겨주시오.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>과제 및 프로젝트/메이플스토리</category>
      <author>joonhee305</author>
      <guid isPermaLink="true">https://joonhee305.tistory.com/71</guid>
      <comments>https://joonhee305.tistory.com/71#entry71comment</comments>
      <pubDate>Tue, 27 May 2025 00:12:19 +0900</pubDate>
    </item>
    <item>
      <title>LibreChat 구글 검색 에이전트 등록하기</title>
      <link>https://joonhee305.tistory.com/70</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;1. 구글 검색 API 받기 검색&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. API키 발급받고 검색엔진 등록&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 검색 엔진 ID 및 API키 LibreChat에 등록하기&lt;/p&gt;</description>
      <author>joonhee305</author>
      <guid isPermaLink="true">https://joonhee305.tistory.com/70</guid>
      <comments>https://joonhee305.tistory.com/70#entry70comment</comments>
      <pubDate>Tue, 4 Feb 2025 13:22:19 +0900</pubDate>
    </item>
    <item>
      <title>#1 Nexon Open API로 데이터 수집하기</title>
      <link>https://joonhee305.tistory.com/69</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Nexon Open API를 가지고 할수있는게 없을까 하다가.. 유저들의 에테르넬 보급률이 얼마나 늘었는지 궁금해졌다. 그래서 Open API에서 데이터를 크롤링해서 메이플 스토리의 유저 히스토리를 수집하고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메이플 Open API에서 수집 가능한 데이터는 랭킹, 레벨, 장비 세트, 착용중인 장비 아이템 정보, 전투력, 스텟 등 정말 많은 데이터를 얻을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 우선적으로 분석할 정보는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 레벨 별 장비세트 분포&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 시간의 흐름에 따른 장비 세트 선호도 변화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 직업 별&amp;nbsp; 장비 세트 선호도&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정도로 정할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 장비 세트같은 경우 17에테, 18에테 처럼 스타포스 수치에 따라 세분화 할 예정이기 때문에 장비 아이템의 정보를 크롤링 해와야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용할 API는 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 유저의 닉네임을 불러 올 랭킹 조회 API&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 닉네임을 기반으로 OCID를 조회하는 API&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. OCID와 날짜를 기반으로 착용중인 장비 정보, 세트 효과 정보&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정도로 좁힐 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 수집 과정은 이어서 작성하겠따.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>과제 및 프로젝트/메이플스토리</category>
      <author>joonhee305</author>
      <guid isPermaLink="true">https://joonhee305.tistory.com/69</guid>
      <comments>https://joonhee305.tistory.com/69#entry69comment</comments>
      <pubDate>Wed, 22 Jan 2025 23:33:15 +0900</pubDate>
    </item>
    <item>
      <title>Tensorflow : dlerror: cudart64_110.dll not found 오류 해결법</title>
      <link>https://joonhee305.tistory.com/68</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;1. CUDA, cuDNN 버전 확인 후 설치&lt;br /&gt;2. 환경변수 확인&lt;br /&gt;3. python이 64bit 인지 확인, Microsoft에서 다운받은건 안될수도있음, python 재설치하면 해결됨&lt;/p&gt;</description>
      <author>joonhee305</author>
      <guid isPermaLink="true">https://joonhee305.tistory.com/68</guid>
      <comments>https://joonhee305.tistory.com/68#entry68comment</comments>
      <pubDate>Sat, 18 Mar 2023 02:22:21 +0900</pubDate>
    </item>
    <item>
      <title>백준 1615 : 교차개수세기</title>
      <link>https://joonhee305.tistory.com/66</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1615&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/1615&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1676301078664&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;1615번: 교차개수세기&quot; data-og-description=&quot;첫 줄에 N과 간선의 개수 M이 주어진다. 그 다음 줄부터 M+1번째 줄까지 두 개의 수(i, j)가 주어지는데 이는 왼쪽 그룹의 i번 정점과 오른쪽 그룹의 j번 정점을 연결하는 간선이 있다는 의미이다. &quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/1615&quot; data-og-url=&quot;https://www.acmicpc.net/problem/1615&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/w8cWr/hyRBWq5IgV/VqWKK9iD9Kp4l2i6M0Ccv0/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1615&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/1615&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/w8cWr/hyRBWq5IgV/VqWKK9iD9Kp4l2i6M0Ccv0/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;1615번: 교차개수세기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫 줄에 N과 간선의 개수 M이 주어진다. 그 다음 줄부터 M+1번째 줄까지 두 개의 수(i, j)가 주어지는데 이는 왼쪽 그룹의 i번 정점과 오른쪽 그룹의 j번 정점을 연결하는 간선이 있다는 의미이다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;풀이&lt;br /&gt;간선을 왼쪽 그룹 기준으로 정렬 후 간선을 하나씩 보면서 오른쪽 점보다 왼쪽에 있는 간선들의 개수를 센다.&lt;br /&gt;세그 트리 이용&lt;br /&gt;&lt;br /&gt;틀린이유&amp;nbsp;&lt;br /&gt;set썼다가 틀림, 그냥 정렬쓰는게 빠르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1676301151860&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include&amp;lt;bits/stdc++.h&amp;gt;
#include&amp;lt;unordered_map&amp;gt;
#include&amp;lt;time.h&amp;gt;


#define MAX 5000001
#define INF 2000000000
#define MOD 1000000000
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair&amp;lt;int, int &amp;gt; pii;
typedef pair&amp;lt;long long, long long&amp;gt; pll;
typedef pair&amp;lt;double, double&amp;gt; pdd;


int dx[8] = { 0, -1, 0, 1, 1, 1, -1, -1 };
int dy[8] = { -1, 0, 1, 0, -1, 1, 1, -1 };

/*
int dx[2][6] = {
    {1, -1, 0, 0 ,1, -1},
    {1, -1, 0, 0, -1, 1}
};
int dy[2][6] = {
    {0, 0, 1, -1 ,1, -1},
    {0, 0, 1, -1, 1, -1}
};*/

//int dx[8] = { -1, -1, 1, 1, -2, -2, 2, 2 };
//int dy[8] = { 2, -2, 2, -2, -1, 1, -1, 1 };

void init() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
}
ll gcd(ll a, ll b) { for (; b; a %= b, swap(a, b)); return a; }
ll lcm(ll a, ll b) { return (a * b) / gcd(a, b); }

/*
class SegmentTree {
public :
    int seg[8001];

    void init(int n) {
        for (int i = n - 1; i &amp;gt;= 1; --i) {
            seg[i] = seg[i &amp;lt;&amp;lt; 1] + seg[i &amp;lt;&amp;lt; 1 | 1];
        }
    }
    
    void update(int start,int end,int node, int idx,int d) {
        //cout &amp;lt;&amp;lt; start &amp;lt;&amp;lt; &quot; : &quot; &amp;lt;&amp;lt; end &amp;lt;&amp;lt; &quot;\n&quot;;
        if (idx &amp;lt; start || end &amp;lt; idx)
            return;

        if (start &amp;lt;= idx &amp;amp;&amp;amp; idx &amp;lt;= end) {
            seg[node] += d;
            if (start == end)
                return;

            int mid = (start + end) / 2;
            update(start, mid, node * 2, idx, d);
            update(mid + 1, end, node * 2 + 1, idx, d);
        }
    }
    int get(int start, int end, int node, int l, int r) {
        if (r &amp;lt; start || end &amp;lt; l)
            return 0;

        if (l &amp;lt;= start &amp;amp;&amp;amp; end &amp;lt;= r) {
            return seg[node];
        }
        else {
            int mid = (start + end) / 2;
            return get(start, mid, node * 2, l, r) + get(mid + 1, end, node * 2 + 1, l, r);
        }
    }
};*/

class SegmentTree {
public:
    int seg[4001] = { 0 };

    void init(int n) {
        for (int i = n; i &amp;gt;= 1; --i) {
            seg[i] = seg[i &amp;lt;&amp;lt; 1] + seg[i &amp;lt;&amp;lt; 1 | 1];
        }
    }

    void update(int idx, int d,int n) {
        seg[idx + n] += d;
        for (idx += n; idx &amp;gt; 1; idx &amp;gt;&amp;gt;= 1) {
            seg[idx &amp;gt;&amp;gt; 1] = seg[idx] + seg[idx ^ 1];
        }

    }
    int get(int l,int r,int n) {
        int res = 0;
        for (l += n, r += n; l &amp;lt; r; l &amp;gt;&amp;gt;= 1, r &amp;gt;&amp;gt;= 1) {
            if (l &amp;amp; 1) res += seg[l++];
            if (r &amp;amp; 1) res += seg[--r];
        }
        return res;
    }
};
SegmentTree segtree;
vector&amp;lt;int&amp;gt; graph[2001];
int main() {
    init();
    int n, m; cin &amp;gt;&amp;gt; n &amp;gt;&amp;gt; m;
    for (int i = 0; i &amp;lt; m; i++) {
        int x, y; cin &amp;gt;&amp;gt; x &amp;gt;&amp;gt; y;
        segtree.seg[y + n]++;
        graph[x].push_back(y);
    }
    segtree.init(n);

    ll ans = 0;
    for (int i = 1; i &amp;lt;= n; i++) {
        sort(graph[i].begin(), graph[i].end());
        for (auto iter = graph[i].begin(); iter != graph[i].end(); iter++) {
            segtree.update(*iter, -1, n);
        }

        for (auto iter = graph[i].begin(); iter != graph[i].end(); iter++) {
            int res = segtree.get(1, *iter, n);
            ans += res;
        }
    }

    cout &amp;lt;&amp;lt; ans &amp;lt;&amp;lt; &quot;\n&quot;;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <author>joonhee305</author>
      <guid isPermaLink="true">https://joonhee305.tistory.com/66</guid>
      <comments>https://joonhee305.tistory.com/66#entry66comment</comments>
      <pubDate>Tue, 14 Feb 2023 00:12:35 +0900</pubDate>
    </item>
    <item>
      <title>도커 메모리 문제</title>
      <link>https://joonhee305.tistory.com/65</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;1. &lt;a href=&quot;https://velog.io/@xonic789/Vmmem-%EC%A0%90%EC%9C%A0%EC%9C%A8-%ED%95%B4%EA%B2%B0%ED%95%98%EA%B8%B0&quot;&gt;Vmmem 점유율 해결하기 (velog.io)&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1676211191934&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Vmmem 점유율 해결하기&quot; data-og-description=&quot;일반 vim 에디터를 사용할 때도 버벅임 현상이 발생.윈도우즈 작업 관리자를 실행해보니, Vmmem이 메인 메모리를 과다하게 할당하고 있었다.파일 탐색기를 열어 %USERPROFILE%를 입력 후 해당 경로에 .&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@xonic789/Vmmem-%EC%A0%90%EC%9C%A0%EC%9C%A8-%ED%95%B4%EA%B2%B0%ED%95%98%EA%B8%B0&quot; data-og-url=&quot;https://velog.io/@xonic789/Vmmem-점유율-해결하기&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/d7uiFe/hyRAmw8gTo/K3D6MKbFMDLxi8TeK9UG21/img.png?width=584&amp;amp;height=98&amp;amp;face=0_0_584_98,https://scrap.kakaocdn.net/dn/bANV6O/hyRBTtlxDy/lT2TK3jqhST7hkxtQKJPr0/img.png?width=584&amp;amp;height=98&amp;amp;face=0_0_584_98,https://scrap.kakaocdn.net/dn/bhsI90/hyRAbvEqQA/HgtG05rae1j9PW5ZHTfFak/img.jpg?width=1440&amp;amp;height=1440&amp;amp;face=0_0_1440_1440&quot;&gt;&lt;a href=&quot;https://velog.io/@xonic789/Vmmem-%EC%A0%90%EC%9C%A0%EC%9C%A8-%ED%95%B4%EA%B2%B0%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@xonic789/Vmmem-%EC%A0%90%EC%9C%A0%EC%9C%A8-%ED%95%B4%EA%B2%B0%ED%95%98%EA%B8%B0&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/d7uiFe/hyRAmw8gTo/K3D6MKbFMDLxi8TeK9UG21/img.png?width=584&amp;amp;height=98&amp;amp;face=0_0_584_98,https://scrap.kakaocdn.net/dn/bANV6O/hyRBTtlxDy/lT2TK3jqhST7hkxtQKJPr0/img.png?width=584&amp;amp;height=98&amp;amp;face=0_0_584_98,https://scrap.kakaocdn.net/dn/bhsI90/hyRAbvEqQA/HgtG05rae1j9PW5ZHTfFak/img.jpg?width=1440&amp;amp;height=1440&amp;amp;face=0_0_1440_1440');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Vmmem 점유율 해결하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;일반 vim 에디터를 사용할 때도 버벅임 현상이 발생.윈도우즈 작업 관리자를 실행해보니, Vmmem이 메인 메모리를 과다하게 할당하고 있었다.파일 탐색기를 열어 %USERPROFILE%를 입력 후 해당 경로에 .&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. cmd에서 wsl --shutdown 명령 이용하기&lt;/p&gt;</description>
      <author>joonhee305</author>
      <guid isPermaLink="true">https://joonhee305.tistory.com/65</guid>
      <comments>https://joonhee305.tistory.com/65#entry65comment</comments>
      <pubDate>Sun, 12 Feb 2023 23:13:22 +0900</pubDate>
    </item>
    <item>
      <title>백준 17469 : 트리의 색깔과 쿼리</title>
      <link>https://joonhee305.tistory.com/64</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/17469&quot;&gt;17469번: 트리의 색깔과 쿼리 (acmicpc.net)&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1674889443753&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;17469번: 트리의 색깔과 쿼리&quot; data-og-description=&quot;N개의 정점으로 구성된 트리가 있다. 각 정점은 1번부터 N번까지 번호가 매겨져있고, 1 이상 10만 이하의 자연수로 표현되는 색깔을 하나 갖고 있다.&amp;nbsp;루트는 1번 정점이고, 트리이기 때문에 임의&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/17469&quot; data-og-url=&quot;https://www.acmicpc.net/problem/17469&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b4SdR1/hyRpIURCxF/SWjZf9SwehAOJNl0qKPgbk/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/17469&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/17469&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b4SdR1/hyRpIURCxF/SWjZf9SwehAOJNl0qKPgbk/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;17469번: 트리의 색깔과 쿼리&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;N개의 정점으로 구성된 트리가 있다. 각 정점은 1번부터 N번까지 번호가 매겨져있고, 1 이상 10만 이하의 자연수로 표현되는 색깔을 하나 갖고 있다.&amp;nbsp;루트는 1번 정점이고, 트리이기 때문에 임의&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;풀이&lt;br /&gt;쿼리 1 x : x와 x의 부모를 잇는 간선 삭제 &lt;br /&gt;=&amp;gt; 오프라인 쿼리로 처리했을 시 거꾸로 x와 x의 부모를 잇는 간선을 추가하는것으로 바꿀 수 있음&lt;br /&gt;쿼리 2 x : x와 연결되어있는 모든 노드들의 색의 종류&lt;br /&gt;=&amp;gt; 트리의 특성 상 x의 가장 최상단 부모의 모든 자식들과 연결할 수 있음 = 최상단 부모의 자식 노드들의 색의 종류를 구하는 것과 같다.&lt;br /&gt;&lt;br /&gt;문제 포인트&lt;br /&gt;1번 쿼리는 총 n-1개 주어진다 = 트리의 간선은 n-1개이며 오프라인 쿼리로 뒤에서부터 처리 할 시 처음엔 아무것도 연결되지 않은 상태로 볼 수 있음&lt;br /&gt;부모와 자식을 연결 할 때는 유니온 파인드를 사용하며 set을 이용해 중복 체크를 한다.&lt;br /&gt;이 때 set끼리 합칠 때 set이 작은쪽부터 큰쪽으로 합치는것이 시간적으로 최적이다. 단순히 합친다면 최악의 경우 n^2이 나오지만 작은쪽에서 큰쪽으로 합친다면 nlogn이 나온다.&lt;br /&gt;참고 : &lt;a href=&quot;https://ryute.tistory.com/52&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ryute.tistory.com/52&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간선을 하나씩 추가해가며 정답을 구하고 역순으로 출력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1674890082041&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include&amp;lt;bits/stdc++.h&amp;gt;
#include&amp;lt;time.h&amp;gt;


#define MAX 5000001
#define INF 2000000000
#define MOD 1000000
using namespace std;
typedef long long ll;
typedef pair&amp;lt;int, int &amp;gt; pii;
typedef pair&amp;lt;long long, long long&amp;gt; pll;
typedef pair&amp;lt;double, double&amp;gt; pdd;

int dx[8] = { 0, -1, 0, 1, 1, 1, -1, -1 };
int dy[8] = { -1, 0, 1, 0, -1, 1, 1, -1 };

/*
int dx[2][6] = {
    {1, -1, 0, 0 ,1, -1},
    {1, -1, 0, 0, -1, 1}
};
int dy[2][6] = {
    {0, 0, 1, -1 ,1, -1},
    {0, 0, 1, -1, 1, -1}
};*/

//int dx[8] = { -1, -1, 1, 1, -2, -2, 2, 2 };
//int dy[8] = { 2, -2, 2, -2, -1, 1, -1, 1 };

void init() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
}
ll gcd(ll a, ll b) { for (; b; a %= b, swap(a, b)); return a; }
ll lcm(ll a, ll b) { return (a * b) / gcd(a, b); }


int pnode[100001];
set&amp;lt;int&amp;gt;* child[100001];
int parent[100001];
int color[100001];
int getParent(int x) {
    if (x == parent[x])
        return x;
    else return parent[x] = getParent(parent[x]);
}

void unionParent(int p,int c) {
    p = getParent(p);
    c = getParent(c);

    if (p == c)
        return;

    if (child[p]-&amp;gt;size() &amp;lt; child[c]-&amp;gt;size()) {
        swap(child[p], child[c]);
    }

    for (auto i : *child[c]) {
        child[p]-&amp;gt;insert(i);
    }
    child[c]-&amp;gt;clear();

    parent[c] = p;
}
int main() {
    init();
    int n, q; cin &amp;gt;&amp;gt; n &amp;gt;&amp;gt; q;
    vector&amp;lt;pii&amp;gt; cmd;
    vector&amp;lt;int&amp;gt; ans;
    //부모 입력받기
    for (int i = 2; i &amp;lt;= n; i++) {
        cin &amp;gt;&amp;gt; pnode[i];
        pnodeSub[i] = pnode[i];
    }
    //색 입력받기
    for (int i = 1; i &amp;lt;= n; i++) {
        cin &amp;gt;&amp;gt; color[i];
    }
    //초기화
    for (int i = 1; i &amp;lt;= n; i++) {
        parent[i] = i;
        child[i] = new set&amp;lt;int&amp;gt;();
        child[i]-&amp;gt;insert(color[i]);
    }

    for (int i = 0; i &amp;lt; n + q - 1; i++) {
        int qn, node; cin &amp;gt;&amp;gt; qn &amp;gt;&amp;gt; node;
        cmd.push_back({ qn,node });
    }

    for (int i = cmd.size() - 1; i &amp;gt;= 0; i--) {
        int qn = cmd[i].first;
        int node = cmd[i].second;
        if (qn == 1) {
            unionParent(pnode[node], node);
        }
        else {
            ans.push_back(child[getParent(node)]-&amp;gt;size());
        }
    }
    for (int i = ans.size() - 1; i &amp;gt;= 0; i--) {
        cout &amp;lt;&amp;lt; ans[i] &amp;lt;&amp;lt; &quot;\n&quot;;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/백준</category>
      <author>joonhee305</author>
      <guid isPermaLink="true">https://joonhee305.tistory.com/64</guid>
      <comments>https://joonhee305.tistory.com/64#entry64comment</comments>
      <pubDate>Sat, 28 Jan 2023 16:14:49 +0900</pubDate>
    </item>
    <item>
      <title>백준 1222 : 홍준 프로그래밍 대회</title>
      <link>https://joonhee305.tistory.com/63</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1222&quot;&gt;1222번: 홍준 프로그래밍 대회 (acmicpc.net)&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1674871311572&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;1222번: 홍준 프로그래밍 대회&quot; data-og-description=&quot;홍준이는 프로그래밍 대회를 개최했다. 이 대회는 사람들이 팀을 이루어서 참가해야 하며, 팀원의 수는 홍준이가 정해준다. 팀원이 홍준이가 정한 값보다 부족하다면, 그 팀은 대회에 참여할 수&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/1222&quot; data-og-url=&quot;https://www.acmicpc.net/problem/1222&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bWX31t/hyRpCmGaDD/lr4ksw9kjmmfCYKx5n9c5k/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1222&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/1222&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bWX31t/hyRpCmGaDD/lr4ksw9kjmmfCYKx5n9c5k/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;1222번: 홍준 프로그래밍 대회&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;홍준이는 프로그래밍 대회를 개최했다. 이 대회는 사람들이 팀을 이루어서 참가해야 하며, 팀원의 수는 홍준이가 정해준다. 팀원이 홍준이가 정한 값보다 부족하다면, 그 팀은 대회에 참여할 수&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;풀이&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 각 팀원들의 약수를 모두 구해 해당 약수들의 개수를 구하고 약수의 개수 * 해당 약수의 값이 가장 큰 값을 찾으려함&lt;br /&gt;-&amp;gt; 약수를 구하는데 sqrt(n)의 시간복잡도가 들어 약 2e8정도의 시간복잡도가 나옴 = AC를 받았으나 빡빡함&lt;br /&gt;2. 1~200만까지의 각 수들의 약수들을 모두 구해놓고 수를 입력받으면 약수들의 개수를 세주는 방법&lt;br /&gt;시간은 nlogn이였으나 약수가 많아 메모리초과가 남&lt;br /&gt;3. 2번을 응용하여 입력받을 때 숫자들의 개수를 기록해놓고 1~200만을 순회하면서 해당 수를 약수로 갖는 수가 몇개인지를 찾음. -&amp;gt; nlogn 의 시간복잡도로 무사히 통과가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간복잡도 O(NlogN) =&amp;gt; N + N/2 + N/3 + N/4 + ... + N/N = N(1 + 1/2 + 1/3 + 1/4 + 1/5 + ... + 1/N), N&amp;lt;=2e6&lt;/p&gt;
&lt;pre id=&quot;code_1674871599352&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include&amp;lt;bits/stdc++.h&amp;gt;
#include&amp;lt;time.h&amp;gt;


#define MAX 5000001
#define INF 2000000000
#define MOD 1000000
using namespace std;
typedef long long ll;
typedef pair&amp;lt;int, int &amp;gt; pii;
typedef pair&amp;lt;long long, long long&amp;gt; pll;
typedef pair&amp;lt;double, double&amp;gt; pdd;

int dx[8] = { 0, -1, 0, 1, 1, 1, -1, -1 };
int dy[8] = { -1, 0, 1, 0, -1, 1, 1, -1 };

/*
int dx[2][6] = {
    {1, -1, 0, 0 ,1, -1},
    {1, -1, 0, 0, -1, 1}
};
int dy[2][6] = {
    {0, 0, 1, -1 ,1, -1},
    {0, 0, 1, -1, 1, -1}
};*/

//int dx[8] = { -1, -1, 1, 1, -2, -2, 2, 2 };
//int dy[8] = { 2, -2, 2, -2, -1, 1, -1, 1 };

void init() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
}
ll gcd(ll a, ll b) { for (; b; a %= b, swap(a, b)); return a; }
ll lcm(ll a, ll b) { return (a * b) / gcd(a, b); }


#define SIZE 2000001
ll cnt[SIZE];
ll num[SIZE];
int main() {
    init();
    int n; cin &amp;gt;&amp;gt; n;
    for (int i = 0; i &amp;lt; n; i++) {
        ll k; cin &amp;gt;&amp;gt; k;
        num[k]++;
    }
    for (int i = 1; i &amp;lt; SIZE; i++) {
        for (int j = i; j &amp;lt; SIZE; j += i) {
            cnt[i] += num[j];
        }
    }
    ll ans = n;
    for (int i = 2; i &amp;lt; SIZE; i++) {
        if(cnt[i]&amp;gt;1)
            ans = max(ans, cnt[i] * i);
    }
    cout &amp;lt;&amp;lt; ans &amp;lt;&amp;lt; &quot;\n&quot;;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/백준</category>
      <author>joonhee305</author>
      <guid isPermaLink="true">https://joonhee305.tistory.com/63</guid>
      <comments>https://joonhee305.tistory.com/63#entry63comment</comments>
      <pubDate>Sat, 28 Jan 2023 11:06:54 +0900</pubDate>
    </item>
    <item>
      <title>스터디 23/01/21 1563 : 개근상</title>
      <link>https://joonhee305.tistory.com/62</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1563&quot;&gt;1563번: 개근상 (acmicpc.net)&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1674827753832&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;1563번: 개근상&quot; data-og-description=&quot;백준중학교에서는 학기가 끝날 무렵에 출결사항을 보고 개근상을 줄 것인지 말 것인지 결정한다. 이 학교는 이상해서 학생들이 학교를 너무 자주 빠지기 때문에, 개근상을 주는 조건이 조금 독&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/1563&quot; data-og-url=&quot;https://www.acmicpc.net/problem/1563&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/HancY/hyRpFpHkEW/jh0dXFUouRjn1UaJdeqZiK/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1563&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/1563&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/HancY/hyRpFpHkEW/jh0dXFUouRjn1UaJdeqZiK/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;1563번: 개근상&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;백준중학교에서는 학기가 끝날 무렵에 출결사항을 보고 개근상을 줄 것인지 말 것인지 결정한다. 이 학교는 이상해서 학생들이 학교를 너무 자주 빠지기 때문에, 개근상을 주는 조건이 조금 독&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;풀이&lt;br /&gt;DP로 풀이한다.&lt;br /&gt;DP[n][l][a] = n번째 날까지 지각을 l번하고 결석을 a번한 경우의 수&lt;br /&gt;지각을 2번하거나 결석을 3번한 경우 0을 리턴하고 n이 끝까지 가면 1을 리턴하여 모든 경우를 구한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간복잡도 : O(n*2*3)&lt;/p&gt;
&lt;pre id=&quot;code_1674827851805&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include&amp;lt;bits/stdc++.h&amp;gt;
#include&amp;lt;time.h&amp;gt;


#define MAX 5000001
#define INF 2000000000
#define MOD 1000000
using namespace std;
typedef long long ll;
typedef pair&amp;lt;int, int &amp;gt; pii;
typedef pair&amp;lt;long long, long long&amp;gt; pll;
typedef pair&amp;lt;double, double&amp;gt; pdd;

int dx[8] = { 0, -1, 0, 1, 1, 1, -1, -1 };
int dy[8] = { -1, 0, 1, 0, -1, 1, 1, -1 };

/*
int dx[2][6] = {
    {1, -1, 0, 0 ,1, -1},
    {1, -1, 0, 0, -1, 1}
};
int dy[2][6] = {
    {0, 0, 1, -1 ,1, -1},
    {0, 0, 1, -1, 1, -1}
};*/

//int dx[8] = { -1, -1, 1, 1, -2, -2, 2, 2 };
//int dy[8] = { 2, -2, 2, -2, -1, 1, -1, 1 };

void init() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
}
ll gcd(ll a, ll b) { for (; b; a %= b, swap(a, b)); return a; }
ll lcm(ll a, ll b) { return (a * b) / gcd(a, b); }

ll dp[1001][2][3];
int n;
int func(int d,int l,int a) {
    if (l &amp;gt;= 2 || a &amp;gt;= 3)
        return 0;
    else if (n == d)
        return 1;

    ll&amp;amp; res = dp[d][l][a];
    if (res != -1) return res;

    res = 0;
    res += func(d + 1, l + 1, 0);
    res %= MOD;
    res += func(d + 1, l, 0);
    res %= MOD;
    res += func(d + 1, l, a + 1);
    res %= MOD;

    return res;
}
int main() {
    init();
    memset(dp, -1, sizeof(dp));
    cin &amp;gt;&amp;gt; n;
    cout&amp;lt;&amp;lt; func(0, 0, 0);
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/백준</category>
      <author>joonhee305</author>
      <guid isPermaLink="true">https://joonhee305.tistory.com/62</guid>
      <comments>https://joonhee305.tistory.com/62#entry62comment</comments>
      <pubDate>Fri, 27 Jan 2023 22:59:44 +0900</pubDate>
    </item>
  </channel>
</rss>