<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>매일 조금씩</title>
    <link>https://gom20.tistory.com/</link>
    <description>학습 기록 저장소</description>
    <language>ko</language>
    <pubDate>Wed, 19 Aug 2026 17:43:53 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>gom20</managingEditor>
    <item>
      <title>[HTTP완벽가이드] 캐시</title>
      <link>https://gom20.tistory.com/312</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;캐시&lt;/b&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;거리로 인한 지연 줄임&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 불필요한 데이터&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 대역폭 병목&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. 갑작스런 요청쇄도&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4. 거리로 인한 지연&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빛의 속도 그 자체가 유의미한 지연 발생&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5. 적중과 부적중&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시 적중 (cache hit), 캐시 부적중(cache miss)&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;캐시된 사본이 충분히 오래된 경우에만 재검사&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원서버에 작은 재검사 요청&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;304 not modified&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;If-Modified-Since 헤더 겟요청 호출 시 보냄&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;304는 해당 캐시된 사본 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;404는 서버객체가 삭제된 케이스로 캐시는 사본삭제&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;40%면 괜찮은 편&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4) 적중과 부적중의 구별&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;date 헤더 이용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;응답의 Date 헤더값의 응답 생성일 체크&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Age 헤더&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;6. 캐시 토폴로지&lt;/h4&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;1) 개인 전용 캐시&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;2) 공용 프락시 캐시&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;3) 프락시 캐시 계층들&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작은 캐시 -&amp;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;4) 캐시망, 콘텐츠 라우팅, 피어링&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시 계층 X 복잡한 캐시망&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;h4 data-ke-size=&quot;size20&quot;&gt;7. 캐시 처리 단계&lt;/h4&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) 검색&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4) 신선도 검사&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5) 응답 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시된 서버 응답 헤더를 토대로 응답헤더 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시는 Date헤더를 조정해서는 안됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6) 발송&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7) 로깅&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;h3 data-ke-size=&quot;size23&quot;&gt;8. 사본을 신선하게 유지하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 문서 만료&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원서버가 각 문서에 유효기간을 붙일 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cache-Control, Expires&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;Expires: Fri, 06 Jul 2002, 05:00:00 GMT&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cache-Control: max-age=484200&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;3) 서버 재검사&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만료 되었을 경우 재검사 요청&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4) 조건부 메서드와 재검사&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시는 서버에 조건부 GET 요청을 보낼 수 있음&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;If-Modified-Since&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;If-None-match: 캐시된 태그가 서버에 있는 문서의 태그와 다를때만 요청 처리&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;5) If-Modified-Since&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 흔히 쓰임&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IMS요청&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;6) If-None-Match&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;일정 시간 간격으로 다시 쓰여져서&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;서버가 최근 변경 일시를 정확하게 판별 X&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;7) 약한 검사기와 강한 검사기&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;8) 언제 엔티티태그? 언제 last-modified일시 사용?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버가 엔티티 태그 반환 했으면 반드시 엔티티 태그 검사기 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Last-modified값만 반환했따면 If-modified-since검사&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;두 조건 모두 부합해야 304 not modified 리턴&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;9. 캐시 제어&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;얼마나 오랫동안 캐시 할 것인지?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cache-Control&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) no-store: 캐시가 사본 만드는 것 금지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) no-cache: 로컬 캐시 저장소에 저장될 수 있지만, 재검사를 무조건 해야한다?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt; 헤더 이름이 헷갈림. 더 나은 이름은 Do-Not-Serve-From-Cache-Without-Revalidatin 이라고 책에 쓰여짐.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) must-revalidate: 원서버와의 최초의 재검사 없이는 사본 제공 X&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4) max-age&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;no-cahce랑 must-revalidate 차이?&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;5) 휴리스틱 만료&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;max-age, expires 없다면 경험적인방법(휴리스틱)으로 최대 나이 계산&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최대 나이 값이 24시간보다 클 경우 Heuristic Expiration 경고 헤더라 추가되어야함&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;LM인자 알고리즘&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;6) 클라이언트 신선도 제약&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;10. 캐시 제어 설정&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;11. 자세한 알고리즘&lt;/h3&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;겉보기 나이를 계산&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;겉보기 나이 = max(0, 응답받은시간 - Date헤더값)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보정된 겉보기 나이 = max(겉보기 나이, age 헤더값)&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;문서가 우리 캐시에 도착했을 때의 나이 = 보정된 겉보기 나이 + 응답 지연 추정값&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;span style=&quot;color: #333333; text-align: start;&quot;&gt;문서가 우리 캐시에 도착했을 때의 나이&lt;span&gt;&amp;nbsp; + 사본이 얼마나 우리 캐시에 있었는지(체류시간)&lt;/span&gt;&lt;/span&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;&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;&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;&amp;nbsp;&lt;/p&gt;</description>
      <category> IT</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/312</guid>
      <comments>https://gom20.tistory.com/312#entry312comment</comments>
      <pubDate>Mon, 16 Oct 2023 18:06:07 +0900</pubDate>
    </item>
    <item>
      <title>[HTTP 완벽가이드] TCP 커넥션 관리</title>
      <link>https://gom20.tistory.com/311</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. TCP 커넥션&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;브라우저가 TCP 커넥션을 통해 웹서버에 요청을 보내는 순서&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 HTTP 통신은 TCP/IP 를 통해 이루어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) URL에서 호스트명 추출&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 호스트명에 대한 IP 주소 추출&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;4) IP와 Port로 TCP 커넥션 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5) HTTP 요청 보냄&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6) HTTP 응답 수신&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7) 커넥션 끊기&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;- TCP 커넥션은 인터넷을 안정적으로 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- HTTP에 신뢰할 수 있는 통신 방식 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 순서에 맞게 정확히 전달&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;TCP 데이터 전송 방식&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세그컨트 단위로 데이터 스트림을 나누고,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세그컨트를 IP패킷에 담아서 인터넷을 통해 데이터 전달&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;- IP 패킷 구성요소&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IP패킷 헤더(IP정보), TCP 세그먼트 헤더(포트번호, 체크섬), TCP 데이터 조각(데이터)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;유일한 TCP 커넥션&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;발신지 IP 주소, 발신지 포트, 수신지 IP주소, 수신지 포트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서로 다른 두 개의 TCP 커넥션은 네 가지 값이 모두 같을 수 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;TCP 소켓 프로그래밍&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소켓 API를 사용하면 TCP 종단에 데이터 구조를 생성하고, 원격 서버 TCP 종단에 그 종단 데이터 구조를 연결하여 데이터 스트림을 읽고 쓸 수 있다.&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;- Client&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;socket()&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;connect() -----&amp;gt; accept()&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;write, read()&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;close()&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;- Server&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;socket()&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;bind()&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;listen()&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;accept()&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;read, write()&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;close()&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;Server&lt;/p&gt;
&lt;pre id=&quot;code_1693459148139&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import socket

# Create a socket object
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Define the server address and port
server_address = ('127.0.0.1', 12345)

# Bind the socket to the server address and port
server_socket.bind(server_address)

# Listen for incoming connections (maximum number of queued connections: 5)
server_socket.listen(5)
print(&quot;Server is listening for connections...&quot;)

while True:
    # Accept a new connection
    client_socket, client_address = server_socket.accept()
    print(f&quot;Connection from {client_address} established.&quot;)

    # Send data to the client
    message = &quot;Hello, client! Welcome to the server.&quot;
    client_socket.send(message.encode())

    # Close the client socket
    client_socket.close()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Client&lt;/p&gt;
&lt;pre id=&quot;code_1693459180926&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import socket

# Create a socket object
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Define the server address and port
server_address = ('127.0.0.1', 12345)

# Connect to the server
client_socket.connect(server_address)

# Receive data from the server
data = client_socket.recv(1024).decode()
print(f&quot;Received: {data}&quot;)

# Close the client socket
client_socket.close()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. TCP 성능 고려&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTTP는 TCP 바로 위에 있는 계층이므로, TCP 성능에 영향을 많이 받음&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;HTTP 트랜잭션 지연&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;호스트에 첫 방문일 경우 DNS 인프라로 호스트명을 IP주소로 변환하는데 시간 소요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;TCP 커넥션 요청 - 허가 응답 회신: 커넥션 설정 시간&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;HTTP 요청 전송&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;HTTP 응답&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;TCP 관련 지연 요소&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- TCP 커넥션 핸드셰이크 지연&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;TCP의 느린 시작&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;네이글 알고리즘&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;TCP의 편승 확인응답&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;TIME_WAIT 지연과 포트고갈&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;TCP 커넥션 핸드셰이크 지연&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;TCP커넥션을 열 때 연속으로 IP패킷 교환&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;작은 크기의 데이터 전송에 커넥셔이 사용된다면 이러한 패킷 교환은 HTTP성능을 크게 저하&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;1) 클라이언트가 새로운 TCP 커넥션을 생성하기 위해 작은 TCP패킷을 서버에게 전송(SYN 플래그)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2) 서버가 그 커넥션을 받으면 몇가지 커넥션 매개 변수 산출. 커넥션 요청이 받아들여졌음을 의미하는 SYN, ACK플래그를 포함한 TCP패킷을 클라이언트에게 전송&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;3) 클라이언트는 커넥션이 잘 맺어졌음을 알리기위해 확인 응답 신호를 보냄 (+ 데이터)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;HTTP 트랜잭션이 큰 데이터가 아닌 경우, 핸드셰이크 지연이 눈에 띔&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;크기가 작은 HTTP트랜잭션은 50%이상의 시간을 TCP를 구성하는데 쓰임&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;확인응답 지연&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인터넷은 패킷전송을 완벽 보장X&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TCP는 성공적 데이터 전송을 보장하기 위해 자체적인 확인 체계&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; TCP 세그먼트는 순번, 무결성 체크섬을 가짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세그먼트 수신자는 세그먼트를 온전히받으면 확인응답 패킷을 송신자에게 반환&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;송신자가 특정시간 안에 확인응답 메시지를 못받으면 패킷 파기 or 오류로 판단하고 데이터 재전송&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;특정 시간 동안 확인응답 패킷을 버퍼에 저장해 두고, 편승 시키기 위한 송출데이터 패킷을 찾음&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;HTTP동작 방식은 요청과 응답 두가지 형식으로 이루어지기 때문에 편승 기회 감소&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;TCP의 느린 시작&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TCP 커넥션 생성 시간에 따라 데이터 전송 속도 달라질 수 있음&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;급작스러운 부하 방지를 위함&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;네이글 알고리즘&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;각 TCP 세그먼트는 40바이트 상당의 플래그 헤더 포함하여 전송.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;작은 크기의 데이터를 포함한 많운 수의 패킷을 전송한다면 네트워크 성능 저하&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;네이글 알고리즘? 패킷 전송 전 많은 양의 TCP 데이터를 한개의 덩어리로 합침&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;세그먼트가 최대 크기가 되지 않으면 전송 X&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;모든 패킷이 확인 응답을 받았을 경우에는 최대 크기보다 작은 패킷 전송 허락&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;문제1 크기가 작은 HTTP메시지는 패킷을 채우지 못하기 때문에 추가적인 데이터를 기다리며 지연&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;문제2 확인 응답지연과 함께 쓰이면, 확인 응답이 도착할 때까지 데이터 전송 멈춤&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;TIME_WAIT 지연과 포트고갈&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TCP종단에서 커넥션을 끊으면 종단에서는 커넥션의 IP, 포트를 메모리의 control block에 기록&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같은 주소와 포트 번호를 사용하는 신규 TCP 커넥션이 일정시간 생성되는 것을 방지 하기 위함 (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;일반적인 종료지연은 문제 X&lt;br /&gt;성능 시험 케이스에서 문제, IP 주소 개수 제한. 부하 발생 컴퓨터 수 제한&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;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. HTTP 커넥션 관리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커넥션을 생성하고 최적화하는 HTTP기술 설명&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Connection 헤더&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTTP는 중개서버가 놓이는 것을 허락 (Proxy)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Connection 헤더 필드는 커넥션 토큰을 쉼표로 구분하여 가짐. 그 값들은 다른 커넥션에 전달 X&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 메시지를 보낸 다음 끊어져야할 커넥션은 Connection: close라고 명시&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;Connection 헤더는 다음 세가지 종류의 토큰 전달 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTTP 헤더 필드, 임시 토큰, close값&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;HTTP 헤더 필드는 현재 커넥션만을 위한 정보로 다음 커넥션에 전달 X&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Connection 헤더에는 홉별 헤더명을 기술 (특정 두 서버 간에만 영향을 미치는 헤더)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;순차적인 트랜잭션 처리에 의한 지연&lt;/h4&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;- 파이프 라인 커넥션&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;h3 data-ke-size=&quot;size23&quot;&gt;4. 병렬 커넥션&lt;/h3&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;나머지 객체를 내려받는 데에 남은 대역폭 사용&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;다수의 커넥션은 메모리 많이 소모 자체 성능 문제&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;h3 data-ke-size=&quot;size23&quot;&gt;5. 지속 커넥션&lt;/h3&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;HTTP/1.1 지원기기는 처리가 완료된 후에도 TCP 커넥션을 유지하여 앞으로 있을 HTTP 요청에 재사용 할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처리가 완료된 후에도 계속 연결된 상태로 있는 TCP커넥션을 지속 커넥션이라고 부른다.&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;TCP의 느린 시작으로 인한 지연을 피함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;지속 커넥션 vs 병렬 커넥션&lt;/h4&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;TCP 느린 시작 때문에 성능 저하&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;튜닝된 커넥션 유지&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;But 관리 X 계속 연결된 커넥션이 쌓일 수 있음-&amp;gt; 불필요한 리소스 소모&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;HTTP/1.0+의 Keep-Alive 커넥션&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커넥션을 맺고 끊는데 필요한 작업이 없어서 시간 단축&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TCP느린 시작 지연 일어나지 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Keep-Alive 동작&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;keep-alive 커넥션을 구현한 클라이언트는 커넥션을 유지하기 위해서 요청에 Connection:Keep-Alive 헤더를 포함&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;h4 data-ke-size=&quot;size20&quot;&gt;Keep-Alive 옵션&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Keep-Alive 헤더는 커넥션을 유지하기를 바라는 요청일 뿐이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무조건 그것을 따를 필요 X&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;timeout 커넥션 유지 시간 (보장X)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;max 몇 개의 HTTP 트랜잭션을 처리할때까지 유지될지 (보장X)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Keep-Alive 헤더는, Connection: Keep-Alive 헤더가 있을 때만 사용할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Keep-Alive 커넥션 제한과 규칙&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프록시와 게이트 웨이는 Connection 헤더 규칙을 철저히 지켜야 함&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메시지를 전달하거나 캐시에 넣기 전에&amp;nbsp;Connection 헤더에 명시된 모든 헤더 필드와 Connection 헤더를 제거 해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정석대로라면 keep-alive커넥션은 Connection 헤더를 인식 못하는 프록시서버와 맺어지면 안되나 현실적으로는 쉽지 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Keep-Alive와 멍청한 프락시&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프록시에서 keep-alive를 사용할 때 생기는 문제&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;b&gt;&amp;nbsp;Connection 헤더의 무조건 전달&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프록시가 Connection 헤더를 이해하지 못해 해당 헤더를 삭제하지 않고 다음 프록시에 전달할 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Connection헤더는 홉별 헤더, 프록시는 Connection 헤더와 Connection 헤더에 명시된 헤더들은 절대 전달하면 안됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Proxy-Connection 살펴보기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적인 Connection 헤더 대신&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비표준인 Proxy-Connection 확장헤더를 프락시에게 전달&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;영리한 프록시라면? proxy-connection 헤더를 connection 헤더로 바꿈으로써 원하는 효과를 얻게 될 것임&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;h4 data-ke-size=&quot;size20&quot;&gt;HTTP/1.1의 지속 커넥션&lt;/h4&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;h4 data-ke-size=&quot;size20&quot;&gt;지속 커넥션의 제한과 규칙&lt;/h4&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;h3 data-ke-size=&quot;size23&quot;&gt;6. 파이프라인 커넥션&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTTP/1.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;&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;- 응답은 요청 순서와 같게 와야 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- POST 요청같이 반복해서 보낼 경우 문제가 생기는 요청은 파이프라인을 통해 보니면 안됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;7. 커넥션 끊기에 대한 미스터리&lt;/h3&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;h4 data-ke-size=&quot;size20&quot;&gt;마음대로 커넥션 끊기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTTP어플리케이션은 언제든지 지속 커넥션을 임의로 끊을 수 있다.&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;h4 data-ke-size=&quot;size20&quot;&gt;Content-Length 와 Truncation&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 응답은 본문의 정확한 크기값을 가지는 Content-Length 헤더를 가지고 있어야 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;커넥션 끊기의 허용, 재시도, 멱등성&lt;/h4&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;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러번 호출할 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GET은 OK&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;POST는 문제발생 여지&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;GET, HEAD, PUT, DELETE, TRACE , OPTION -&amp;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;PUT과 DELETE는 왜 멱등이지?&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;POST는 비멱등&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;POST와 같은 요청은 파이프라인을 통해 요청하면 안된다.&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;비멱등인 요청을 다시 보내야 한다면, 응답을 받을때까지 기다려야 한다.&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;h4 data-ke-size=&quot;size20&quot;&gt;우아한 커넥션 끊기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TCP커넥션은 양방향&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;b&gt;전체 끊기와 절반 끊기&lt;/b&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;close를 호출하면 입력, 출력 모두 끊음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;shutdown은 절반 끊기&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;b&gt;TCP 끊기와 리셋 에러&lt;/b&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;보통은 커넥션의 출력채널을 끊는 것이 안전&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;b&gt;우아하게 커넥션 끊기&lt;/b&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> IT</category>
      <category>HTTP 완벽 가이드</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/311</guid>
      <comments>https://gom20.tistory.com/311#entry311comment</comments>
      <pubDate>Thu, 31 Aug 2023 16:58:39 +0900</pubDate>
    </item>
    <item>
      <title>[git] git 헷갈리는 부분 정리</title>
      <link>https://gom20.tistory.com/310</link>
      <description>&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;git을 혼자만 쓰다보니 쓰는 기능이 한정되어 있고, 직전 실무는 SVN을 썼고 브랜치 전략이란게... 없었다.&lt;br&gt;아주 오래전 git flow 를 경험해본적이 있지만 잘 기억이 나지 않아 한번 정리해보았다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;git master branch의 default name&lt;/b&gt;&lt;/h4&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;master vs main&amp;nbsp;&lt;br&gt;예전에는 master로 default name이 사용됨&lt;br&gt;요즘에는 main이 default name으로 생성됨&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;origin : remote repository url을 참조하기 위한 alias같은 것.&lt;br&gt;remote: origin이 참조하는 remote repository에 특정 커맨드를 수행하기 위해 사용하는 커맨드&lt;/p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;458&quot; data-origin-height=&quot;91&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c8FJUi/btsbVel7LLo/zGtb7zl5bKYaBczfkqDLWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c8FJUi/btsbVel7LLo/zGtb7zl5bKYaBczfkqDLWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c8FJUi/btsbVel7LLo/zGtb7zl5bKYaBczfkqDLWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc8FJUi%2FbtsbVel7LLo%2FzGtb7zl5bKYaBczfkqDLWk%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;458&quot; height=&quot;91&quot; data-origin-width=&quot;458&quot; data-origin-height=&quot;91&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;pull과 fetch의 차이&lt;/b&gt;&lt;/h4&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;pull: remote repository의 내용을 가져와 자동 병합 (fetch + merge)&lt;br&gt;fetch: remote repository의 내용을 확인하고 로컬 데이터와 병합은 하고 싶지 않은 경우 사용&lt;br&gt;fetch를 실행하면 최신 커밋 이력을 이름없는 브랜치로 로컬에 가져옴&lt;br&gt;FETCH_HEAD로 체크아웃 가능&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;git flow 기본 개념&lt;/b&gt;&lt;/h4&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;main: backbone과 같은 중심기점 브랜치, 운영 소스&lt;br&gt;stage:&amp;nbsp;&lt;br&gt;develop: 개발 서버에 배포되는 브랜치&lt;br&gt;relase(임시)&lt;br&gt;feature(임시): 이슈 브랜치, 기능 별 브랜치&lt;br&gt;hotfix(임시): 배포된 소스코드에 버그가 발견되면 생성하여 관리하는 브랜치&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;git 연습&lt;/b&gt;&lt;/h4&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;main, develop 브랜치로 이것 저것 연습해볼까 한다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;b&gt;1. main, develop repository 생성&lt;/b&gt;&lt;br&gt;1-1. main 브랜치 생성&lt;br&gt;일단 기본적으로 repository를 생성하고&amp;nbsp; git clone을 하면&amp;nbsp;main 브랜치가 생성됨&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1118&quot; data-origin-height=&quot;104&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dhSxMa/btsbXJ7gbBP/DoqQVfL83zwfKOM5vuXNuk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dhSxMa/btsbXJ7gbBP/DoqQVfL83zwfKOM5vuXNuk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dhSxMa/btsbXJ7gbBP/DoqQVfL83zwfKOM5vuXNuk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdhSxMa%2FbtsbXJ7gbBP%2FDoqQVfL83zwfKOM5vuXNuk%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;1118&quot; height=&quot;104&quot; data-origin-width=&quot;1118&quot; data-origin-height=&quot;104&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;350&quot; data-origin-height=&quot;57&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bndj1C/btsbToiL8KQ/dcyUi2IDjVK0vkUsjJG7lK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bndj1C/btsbToiL8KQ/dcyUi2IDjVK0vkUsjJG7lK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bndj1C/btsbToiL8KQ/dcyUi2IDjVK0vkUsjJG7lK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbndj1C%2FbtsbToiL8KQ%2FdcyUi2IDjVK0vkUsjJG7lK%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;350&quot; height=&quot;57&quot; data-origin-width=&quot;350&quot; data-origin-height=&quot;57&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;1-2. develop 브랜치 만들기&lt;/p&gt;&lt;figure class=&quot;imageblock floatLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;397&quot; data-origin-height=&quot;88&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKV6mV/btsb5kTuIVq/NlrxcVUjVPLIo95asTIQIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKV6mV/btsb5kTuIVq/NlrxcVUjVPLIo95asTIQIk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKV6mV/btsb5kTuIVq/NlrxcVUjVPLIo95asTIQIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKV6mV%2Fbtsb5kTuIVq%2FNlrxcVUjVPLIo95asTIQIk%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;397&quot; height=&quot;88&quot; data-origin-width=&quot;397&quot; data-origin-height=&quot;88&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;아직 로컬에만 만들어진 상태이다.&lt;br&gt;리모트에 올려보자.&lt;/p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;540&quot; data-origin-height=&quot;260&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9zusm/btsbTv9WJsO/XUhQ2VkCdWhSy2jRwrwUMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9zusm/btsbTv9WJsO/XUhQ2VkCdWhSy2jRwrwUMk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9zusm/btsbTv9WJsO/XUhQ2VkCdWhSy2jRwrwUMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9zusm%2FbtsbTv9WJsO%2FXUhQ2VkCdWhSy2jRwrwUMk%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;540&quot; height=&quot;260&quot; data-origin-width=&quot;540&quot; data-origin-height=&quot;260&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;1-3. main에 직접 소스를 push&amp;nbsp; 할 수 없도록 브랜치 설정을 github에서 해보자.&lt;br&gt;github &amp;gt; settings &amp;gt; branch&amp;nbsp;&lt;br&gt;pull request를 통해서 merge 하도록 설정&lt;br&gt;직접 push못하게 막음&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;999&quot; data-origin-height=&quot;552&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cF9Ghg/btsbVcok0Od/gENhXI0GPrD57k8s8NyGM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cF9Ghg/btsbVcok0Od/gENhXI0GPrD57k8s8NyGM1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cF9Ghg/btsbVcok0Od/gENhXI0GPrD57k8s8NyGM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcF9Ghg%2FbtsbVcok0Od%2FgENhXI0GPrD57k8s8NyGM1%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;999&quot; height=&quot;552&quot; data-origin-width=&quot;999&quot; data-origin-height=&quot;552&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;699&quot; data-origin-height=&quot;85&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HmI0l/btsbV53EYSg/JR9PNWOFIc6h23fBLftbX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HmI0l/btsbV53EYSg/JR9PNWOFIc6h23fBLftbX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HmI0l/btsbV53EYSg/JR9PNWOFIc6h23fBLftbX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHmI0l%2FbtsbV53EYSg%2FJR9PNWOFIc6h23fBLftbX0%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;699&quot; height=&quot;85&quot; data-origin-width=&quot;699&quot; data-origin-height=&quot;85&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;br&gt;&lt;b&gt;2. feature 브랜치 생성해서 작업하고 develop에 merge, main에 pull request까지&lt;/b&gt;&lt;br&gt;feature브랜치는 기본적으로 develop브랜치에서 딴다고 함. (프로젝트 별로 다를 수 있음)&lt;br&gt;나는 main에서 따봤는데, 일반적으로 hotfix가 이런식으로 진행됨&lt;/p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;446&quot; data-origin-height=&quot;176&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c4iXdU/btsbSEMXJfq/CMNujxlqKgKIxqtSpKpkX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c4iXdU/btsbSEMXJfq/CMNujxlqKgKIxqtSpKpkX1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c4iXdU/btsbSEMXJfq/CMNujxlqKgKIxqtSpKpkX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc4iXdU%2FbtsbSEMXJfq%2FCMNujxlqKgKIxqtSpKpkX1%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;446&quot; height=&quot;176&quot; data-origin-width=&quot;446&quot; data-origin-height=&quot;176&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;605&quot; data-origin-height=&quot;426&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uTX7x/btsb1QSG2bP/j5qDWhleK1TzrzWTlUwcu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uTX7x/btsb1QSG2bP/j5qDWhleK1TzrzWTlUwcu1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uTX7x/btsb1QSG2bP/j5qDWhleK1TzrzWTlUwcu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuTX7x%2Fbtsb1QSG2bP%2Fj5qDWhleK1TzrzWTlUwcu1%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;605&quot; height=&quot;426&quot; data-origin-width=&quot;605&quot; data-origin-height=&quot;426&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;2-1. feature 브랜치 만들어서 작업후 커밋, 푸쉬&lt;br&gt;2-2. develop에 feature 변경점 merge하기&lt;/p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;527&quot; data-origin-height=&quot;193&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uW9lt/btsbVcPpL0P/r1l8qvm9giBkks47GQNtTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uW9lt/btsbVcPpL0P/r1l8qvm9giBkks47GQNtTK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uW9lt/btsbVcPpL0P/r1l8qvm9giBkks47GQNtTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuW9lt%2FbtsbVcPpL0P%2Fr1l8qvm9giBkks47GQNtTK%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;527&quot; height=&quot;193&quot; data-origin-width=&quot;527&quot; data-origin-height=&quot;193&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;2-3. main에 pull request하기&lt;br&gt;github &amp;gt; pull request&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1095&quot; data-origin-height=&quot;586&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMRoRI/btsbTob1KpY/gXaQ8QW30eNoi4FJrFKVek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMRoRI/btsbTob1KpY/gXaQ8QW30eNoi4FJrFKVek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMRoRI/btsbTob1KpY/gXaQ8QW30eNoi4FJrFKVek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMRoRI%2FbtsbTob1KpY%2FgXaQ8QW30eNoi4FJrFKVek%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;1095&quot; height=&quot;586&quot; data-origin-width=&quot;1095&quot; data-origin-height=&quot;586&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;br&gt;&lt;b&gt;3. cherry pick 써보기&lt;/b&gt;&lt;br&gt;특정 commit만 찝어서 현재 Head가 가리키는 branch에 추가하는 방법&lt;br&gt;3-1. feature 브랜치에서 commit 두 번 수행&lt;br&gt;commit1) commit1파일 생성&lt;br&gt;commit2) commit2파일 생성&lt;br&gt;&amp;nbsp;&lt;br&gt;3-2. git develop으로 체크아웃 후, 체리픽으로 feature 브랜치에서 수행한 커밋중&lt;br&gt;마지막 커밋내용(커밋 hash) 을 추가해보기&lt;/p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;741&quot; data-origin-height=&quot;354&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3iSPV/btsbTwgHaUd/QuLED4hELlLIq5VGiHdml0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3iSPV/btsbTwgHaUd/QuLED4hELlLIq5VGiHdml0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3iSPV/btsbTwgHaUd/QuLED4hELlLIq5VGiHdml0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3iSPV%2FbtsbTwgHaUd%2FQuLED4hELlLIq5VGiHdml0%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;741&quot; height=&quot;354&quot; data-origin-width=&quot;741&quot; data-origin-height=&quot;354&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;br&gt;&lt;b&gt;4. rebase&lt;/b&gt;&lt;br&gt;4-1. main 에서 feature3 브랜치 생성&lt;br&gt;git checkout main&lt;br&gt;git branch feature3&lt;br&gt;&amp;nbsp;&lt;br&gt;4-2. main 작업&amp;nbsp;&lt;br&gt;C1, C2&lt;br&gt;PS&amp;nbsp;C:\Workspace\git-flow-practice&amp;gt;&amp;nbsp;git&amp;nbsp;add&amp;nbsp;.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;PS&amp;nbsp;C:\Workspace\git-flow-practice&amp;gt;&amp;nbsp;git&amp;nbsp;commit&amp;nbsp;-m&amp;nbsp;'C1' &lt;br&gt;[main&amp;nbsp;5469492]&amp;nbsp;C1 &lt;br&gt;&amp;nbsp;1&amp;nbsp;file&amp;nbsp;changed,&amp;nbsp;1&amp;nbsp;insertion(+),&amp;nbsp;3&amp;nbsp;deletions(-) &lt;br&gt;PS&amp;nbsp;C:\Workspace\git-flow-practice&amp;gt;&amp;nbsp;git&amp;nbsp;add&amp;nbsp;. &lt;br&gt;PS&amp;nbsp;C:\Workspace\git-flow-practice&amp;gt;&amp;nbsp;git&amp;nbsp;commit&amp;nbsp;-m&amp;nbsp;'C2' &lt;br&gt;[main&amp;nbsp;84be1d5]&amp;nbsp;C2 &lt;br&gt;&amp;nbsp;1&amp;nbsp;file&amp;nbsp;changed,&amp;nbsp;2&amp;nbsp;insertions(+) &lt;br&gt;PS&amp;nbsp;C:\Workspace\git-flow-practice&amp;gt;&amp;nbsp;git&amp;nbsp;push&amp;nbsp;origin&amp;nbsp;main&lt;br&gt;&amp;nbsp;&lt;br&gt;4-3. feature 작업&lt;br&gt;PS&amp;nbsp;C:\Workspace\git-flow-practice&amp;gt;&amp;nbsp;git&amp;nbsp;add&amp;nbsp;. &lt;br&gt;PS&amp;nbsp;C:\Workspace\git-flow-practice&amp;gt;&amp;nbsp;git&amp;nbsp;commit&amp;nbsp;-m&amp;nbsp;'C3' &lt;br&gt;[feature3&amp;nbsp;708e983]&amp;nbsp;C3 &lt;br&gt;&amp;nbsp;1&amp;nbsp;file&amp;nbsp;changed,&amp;nbsp;0&amp;nbsp;insertions(+),&amp;nbsp;0&amp;nbsp;deletions(-) &lt;br&gt;&amp;nbsp;create&amp;nbsp;mode&amp;nbsp;100644&amp;nbsp;feature.js &lt;br&gt;PS&amp;nbsp;C:\Workspace\git-flow-practice&amp;gt;&amp;nbsp;git&amp;nbsp;add&amp;nbsp;. &lt;br&gt;PS&amp;nbsp;C:\Workspace\git-flow-practice&amp;gt;&amp;nbsp;git&amp;nbsp;commit&amp;nbsp;-m&amp;nbsp;'C4' &lt;br&gt;[feature3&amp;nbsp;a8a5014]&amp;nbsp;C4 &lt;br&gt;&amp;nbsp;1&amp;nbsp;file&amp;nbsp;changed,&amp;nbsp;3&amp;nbsp;insertions(+) &lt;br&gt;PS&amp;nbsp;C:\Workspace\git-flow-practice&amp;gt;&amp;nbsp;git&amp;nbsp;add&amp;nbsp;. &lt;br&gt;PS&amp;nbsp;C:\Workspace\git-flow-practice&amp;gt;&amp;nbsp;git&amp;nbsp;commit&amp;nbsp;-m&amp;nbsp;'C5'&amp;nbsp;&lt;br&gt;PS&amp;nbsp;C:\Workspace\git-flow-practice&amp;gt;&amp;nbsp;git&amp;nbsp;push&amp;nbsp;origin&amp;nbsp;feature3&lt;br&gt;&amp;nbsp;&lt;br&gt;4-4. rebase main &amp;amp; squash commit&lt;/p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;734&quot; data-origin-height=&quot;204&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNDyZ0/btsrB6mwUGJ/F9NVK4HtLHam99JeuHOsq0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNDyZ0/btsrB6mwUGJ/F9NVK4HtLHam99JeuHOsq0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNDyZ0/btsrB6mwUGJ/F9NVK4HtLHam99JeuHOsq0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNDyZ0%2FbtsrB6mwUGJ%2FF9NVK4HtLHam99JeuHOsq0%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;734&quot; height=&quot;204&quot; data-origin-width=&quot;734&quot; data-origin-height=&quot;204&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;:wq&lt;br&gt;&amp;nbsp;&lt;br&gt;commit 메시지 수정&lt;/p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;686&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dqoAxS/btsrEoGtO5g/hOlKZPqtZFk3Gd8erCeT4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dqoAxS/btsrEoGtO5g/hOlKZPqtZFk3Gd8erCeT4k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dqoAxS/btsrEoGtO5g/hOlKZPqtZFk3Gd8erCeT4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdqoAxS%2FbtsrEoGtO5g%2FhOlKZPqtZFk3Gd8erCeT4k%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;686&quot; height=&quot;180&quot; data-origin-width=&quot;686&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;664&quot; data-origin-height=&quot;222&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/u0vOs/btsrDEitQVt/R2FUxMU8XzMK6m76H8tGq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/u0vOs/btsrDEitQVt/R2FUxMU8XzMK6m76H8tGq1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/u0vOs/btsrDEitQVt/R2FUxMU8XzMK6m76H8tGq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fu0vOs%2FbtsrDEitQVt%2FR2FUxMU8XzMK6m76H8tGq1%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;664&quot; height=&quot;222&quot; data-origin-width=&quot;664&quot; data-origin-height=&quot;222&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;br&gt;4-5. git push&lt;br&gt;이미 push된 상태라면 --force&lt;br&gt;그냥 push하면 아래와 같은 에러&amp;nbsp;&lt;br&gt;리모트의 변경사항과 호환되지 않아서인듯&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;290&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eNirNY/btsrBpT77Q3/ws7gnfOsZ0kgZ2xkA8qL30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eNirNY/btsrBpT77Q3/ws7gnfOsZ0kgZ2xkA8qL30/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eNirNY/btsrBpT77Q3/ws7gnfOsZ0kgZ2xkA8qL30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeNirNY%2FbtsrBpT77Q3%2Fws7gnfOsZ0kgZ2xkA8qL30%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;807&quot; height=&quot;290&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;290&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;force push후 git graph&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1128&quot; data-origin-height=&quot;121&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sCIIy/btsrB1yIRui/2Qt0RhXK2jE1r1Lx90CWFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sCIIy/btsrB1yIRui/2Qt0RhXK2jE1r1Lx90CWFK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sCIIy/btsrB1yIRui/2Qt0RhXK2jE1r1Lx90CWFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsCIIy%2FbtsrB1yIRui%2F2Qt0RhXK2jE1r1Lx90CWFK%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;1128&quot; height=&quot;121&quot; data-origin-width=&quot;1128&quot; data-origin-height=&quot;121&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;br&gt;4-6. 충돌 났을 때는?&lt;br&gt;충돌 파일 해결 후&lt;br&gt;git add .&amp;nbsp;&lt;br&gt;git rebase --continue&lt;br&gt;&amp;nbsp;&lt;br&gt;continue 하면 해당 commit의 message 수정할 수 있는데&amp;nbsp;&lt;br&gt;초반에 여러 커밋을 squash 한다고 설정했다면 그냥 넘어가면됨&lt;br&gt;마지막에 전체 커밋 메시지 수정하는 페이지에서 수정하면 됨&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category> IT</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/310</guid>
      <comments>https://gom20.tistory.com/310#entry310comment</comments>
      <pubDate>Sun, 23 Apr 2023 16:31:15 +0900</pubDate>
    </item>
    <item>
      <title>[Kotiln] No default constructor for entity</title>
      <link>https://gom20.tistory.com/309</link>
      <description>&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;906&quot; data-origin-height=&quot;59&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pxMzj/btr6pdrLHNx/Tnh317eMwehpxmFIQdvNCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pxMzj/btr6pdrLHNx/Tnh317eMwehpxmFIQdvNCk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pxMzj/btr6pdrLHNx/Tnh317eMwehpxmFIQdvNCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpxMzj%2Fbtr6pdrLHNx%2FTnh317eMwehpxmFIQdvNCk%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;906&quot; height=&quot;59&quot; data-origin-width=&quot;906&quot; data-origin-height=&quot;59&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;엔티티 인스턴스 생성 시 발생하는 기본 생성자 없음 오류&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div&gt; 
 &lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;기존 Java + spring boot 조합에서는 lombok을 설치해서 @NoArgsConstructor 어노테이션 사용.&lt;/span&gt;&lt;/p&gt; 
 &lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Kotlin에서는 dataClass를 지원하여 lombok의 대다수의 기능을 대체. lombok 사용 안하고 어떻게 해결?&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;/span&gt;&lt;/p&gt; 
 &lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt; 
&lt;/div&gt;&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;해결&lt;/b&gt;&lt;/h2&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;kotlin-jpa plugin 설치하면&lt;/b&gt;&lt;br&gt;@Entity &lt;br&gt;@Embeddable &lt;br&gt;@MappedSuperclass&lt;br&gt;의 기본 생성자 자동 생성&lt;/p&gt;&lt;div&gt; 
 &lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;plugins {
   kotlin(&quot;plugin.jpa&quot;) version &quot;1.6.10&quot;
}&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt;</description>
      <category> IT</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/309</guid>
      <comments>https://gom20.tistory.com/309#entry309comment</comments>
      <pubDate>Mon, 27 Mar 2023 16:07:21 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 숫자 변환하기 (Python)</title>
      <link>https://gom20.tistory.com/307</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/154538&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/154538&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678151402857&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;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/154538&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bTcbmq/hyRQuBTBRg/TBN1pC32pGyNm2CMoh45DK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/b0lszK/hyRQrkQOR2/rL5ZEdSDY5f7GrDsGHQUN0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/154538&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/154538&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bTcbmq/hyRQuBTBRg/TBN1pC32pGyNm2CMoh45DK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/b0lszK/hyRQrkQOR2/rL5ZEdSDY5f7GrDsGHQUN0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;programmers.co.kr&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BFS로 풀면 됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 6번 테스트 케이스에서 계속 틀림&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;y가 x값과 같을 수 있음을 고려하지못함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt; if x == y : return 0 추가&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1678151467522&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from collections import deque

def solution(x, y, n):
    INF = 1e9
    dp = [INF] * (y+1)
    
    q = deque()
    q.append((x, 0))
    
    while q:
        num, cnt = q.popleft()
        for next_num in (num+n, num*2, num*3):
            if next_num &amp;gt; y:
                continue
            if dp[next_num] == INF:
                dp[next_num] = cnt + 1
                q.append((next_num, cnt + 1))
    
    if x == y: 
        return 0
    elif dp[y] == INF:
        return -1
    else: 
        return dp[y]&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/Programmers</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/307</guid>
      <comments>https://gom20.tistory.com/307#entry307comment</comments>
      <pubDate>Tue, 7 Mar 2023 10:11:29 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 덧칠하기 (Python)</title>
      <link>https://gom20.tistory.com/306</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/161989&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/161989&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678148626852&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;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/161989&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/4SnZR/hyRRM8SsIx/hSvu7n2LUmsKNFKMxc278k/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/Fq37o/hyRQvt88Ly/1zHJKVzrpEzh4MZqo6sEC1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/161989&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/161989&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/4SnZR/hyRRM8SsIx/hSvu7n2LUmsKNFKMxc278k/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/Fq37o/hyRQvt88Ly/1zHJKVzrpEzh4MZqo6sEC1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;programmers.co.kr&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;롤러로 칠한 구역의 마지막 index를 기억했다가&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 칠할 구역이 해당 index보다 커지면 덧칠횟수를 증가시키고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막 index를 갱신한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1678148641673&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(n, m, section):
    answer = 0
    lastidx = 0   
    for i in section:
        if i &amp;gt; lastidx:
            answer += 1
            lastidx = i + m -1 
    
    return answer&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/Programmers</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/306</guid>
      <comments>https://gom20.tistory.com/306#entry306comment</comments>
      <pubDate>Tue, 7 Mar 2023 09:24:57 +0900</pubDate>
    </item>
    <item>
      <title>개인정보처리방침</title>
      <link>https://gom20.tistory.com/300</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;등산왕은(는) 「개인정보 보호법」 제30조에 따라 정보주체의 개인정보를 보호하고 이와 관련한 고충을 신속하고 원활하게 처리할 수 있도록 하기 위하여 다음과 같이 개인정보 처리방침을 수립&amp;middot;공개합니다.&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;span&gt;&lt;span&gt; 조회 및 변경&lt;/span&gt;하는 데이터는 사용자의 휴대 기기에만 저장됩니다. 등산왕은(는) 별도로 개인정보를 수집하거나 처리하지 않습니다.&lt;/span&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;b&gt;제1조(개인정보의 처리목적)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;등산왕은(는) 별도로 개인 정보를 수집하거나 처리하지 않습니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&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;b&gt;제2조(개인정보의&amp;nbsp;처리&amp;nbsp;및&amp;nbsp;보유&amp;nbsp;기간)&lt;/b&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;&lt;b&gt;제3조 (개인정보의 제3자 제공에 관한 사항)&lt;/b&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;&lt;b&gt;제4조 (개인정보 보호책임자 작성)&lt;/b&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;br /&gt;이메일 : ukgom20@gmail.com&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;b&gt;제5조 (개인정보 처리방침 변경)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;①이 개인정보처리방침은 시행일로부터 적용되며, 법령 및 방침에 따른 변경내용의 추가, 삭제 및 정정이 있는 경우에는 변경사항의 시행 7일 전부터 공지사항을 통하여 고지할 것입니다.&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;2023-02-03 최종 업데이트&lt;/p&gt;</description>
      <category>MountainGo</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/300</guid>
      <comments>https://gom20.tistory.com/300#entry300comment</comments>
      <pubDate>Fri, 3 Feb 2023 11:44:39 +0900</pubDate>
    </item>
    <item>
      <title>[Expo] React Native 프로젝트 apk파일로 빌드</title>
      <link>https://gom20.tistory.com/298</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. eas.json에서 buildType apk로 설정&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;eas.json&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1674792173605&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
    &quot;cli&quot;: {
        &quot;version&quot;: &quot;&amp;gt;= 3.4.1&quot;
    },
    &quot;build&quot;: {
        &quot;development&quot;: {
            &quot;developmentClient&quot;: true,
            &quot;distribution&quot;: &quot;internal&quot;
        },
        &quot;preview&quot;: {
            &quot;distribution&quot;: &quot;internal&quot;
        },
        &quot;production&quot;: {
            &quot;android&quot;: {
                &quot;buildType&quot;: &quot;apk&quot;
            }
        }
    },
    &quot;submit&quot;: {
        &quot;production&quot;: {}
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 빌드 명령어 실행&lt;/h4&gt;
&lt;pre id=&quot;code_1674794175414&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;eas build --profile production --platform android&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- expo 로그인이 안되어있다면, 로그인 진행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Build details에 url이 표시되는데 url을 클릭하면 아래와 같이 빌드 상태를 확인 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Expo 에서 빌드가 이루어지기 때문에 느린 편이고, queue에 진입하는데 있어서 대기가 있을 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;965&quot; data-origin-height=&quot;906&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EjJLS/btrXhmMMCc6/n7JcUYfCqWK0PL8T3zWx71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EjJLS/btrXhmMMCc6/n7JcUYfCqWK0PL8T3zWx71/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EjJLS/btrXhmMMCc6/n7JcUYfCqWK0PL8T3zWx71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEjJLS%2FbtrXhmMMCc6%2Fn7JcUYfCqWK0PL8T3zWx71%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;965&quot; height=&quot;906&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;965&quot; data-origin-height=&quot;906&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. APK 다운로드&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빌드가 완료되면 apk url이 터미널에 표시된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;226&quot; data-origin-height=&quot;47&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHLzUO/btrXhPBfPAW/ZZZYDctkbI1ss3C44iQkKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHLzUO/btrXhPBfPAW/ZZZYDctkbI1ss3C44iQkKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHLzUO/btrXhPBfPAW/ZZZYDctkbI1ss3C44iQkKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHLzUO%2FbtrXhPBfPAW%2FZZZYDctkbI1ss3C44iQkKK%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;226&quot; height=&quot;47&quot; data-origin-width=&quot;226&quot; data-origin-height=&quot;47&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>MountainGo</category>
      <category>Android</category>
      <category>apk</category>
      <category>build</category>
      <category>expo</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/298</guid>
      <comments>https://gom20.tistory.com/298#entry298comment</comments>
      <pubDate>Fri, 27 Jan 2023 13:13:19 +0900</pubDate>
    </item>
    <item>
      <title>[MariaDB] 테이블 대소문자 구분 해제</title>
      <link>https://gom20.tistory.com/297</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;lower case 구분 여부 확인&lt;/h4&gt;
&lt;pre id=&quot;code_1674777776647&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;show variables like 'lower_case_table_names';&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;556&quot; data-origin-height=&quot;120&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lTX6d/btrXibp8qGh/hwla8kLsexFhaJ02xTKxs0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lTX6d/btrXibp8qGh/hwla8kLsexFhaJ02xTKxs0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lTX6d/btrXibp8qGh/hwla8kLsexFhaJ02xTKxs0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlTX6d%2FbtrXibp8qGh%2Fhwla8kLsexFhaJ02xTKxs0%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;758&quot; height=&quot;120&quot; data-origin-width=&quot;556&quot; data-origin-height=&quot;120&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0일 경우 대소문자를 구분함&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;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;server.cnf 수정&lt;/h4&gt;
&lt;pre id=&quot;code_1674778565867&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;vi /etc/my.cnf.d/server.cnf&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;lower_case_table_names=1 입력&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;484&quot; data-origin-height=&quot;61&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2rOs0/btrXimLTG3M/S402lPQnViP3LZLBTbx6Vk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2rOs0/btrXimLTG3M/S402lPQnViP3LZLBTbx6Vk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2rOs0/btrXimLTG3M/S402lPQnViP3LZLBTbx6Vk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2rOs0%2FbtrXimLTG3M%2FS402lPQnViP3LZLBTbx6Vk%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;484&quot; height=&quot;61&quot; data-origin-width=&quot;484&quot; data-origin-height=&quot;61&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;확인&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;533&quot; data-origin-height=&quot;120&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wAnIz/btrXlihFC65/yK11niboUNJnIzsTHDOIW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wAnIz/btrXlihFC65/yK11niboUNJnIzsTHDOIW0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wAnIz/btrXlihFC65/yK11niboUNJnIzsTHDOIW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwAnIz%2FbtrXlihFC65%2FyK11niboUNJnIzsTHDOIW0%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;533&quot; height=&quot;120&quot; data-origin-width=&quot;533&quot; data-origin-height=&quot;120&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>MountainGo</category>
      <category>MariaDB</category>
      <category>대소문자</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/297</guid>
      <comments>https://gom20.tistory.com/297#entry297comment</comments>
      <pubDate>Fri, 27 Jan 2023 09:16:42 +0900</pubDate>
    </item>
    <item>
      <title>[Spring Boot] Gradke bootJar 배포 (Eclipse)</title>
      <link>https://gom20.tistory.com/296</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;Run As &amp;gt; Run Configurations &amp;gt; Gradle Task 선택&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;bootJar 입력&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;956&quot; data-origin-height=&quot;677&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6weIh/btrXgqVvS7h/rjsRdh4VKVAFVLxPuMT921/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6weIh/btrXgqVvS7h/rjsRdh4VKVAFVLxPuMT921/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6weIh/btrXgqVvS7h/rjsRdh4VKVAFVLxPuMT921/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6weIh%2FbtrXgqVvS7h%2FrjsRdh4VKVAFVLxPuMT921%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;705&quot; height=&quot;677&quot; data-origin-width=&quot;956&quot; data-origin-height=&quot;677&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Jar파일 확인&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트 폴더 &amp;gt; build &amp;gt; libs&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;612&quot; data-origin-height=&quot;164&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9RXjB/btrXhmY6NwE/iVPCwBggLjMHt6p9nEQPd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9RXjB/btrXhmY6NwE/iVPCwBggLjMHt6p9nEQPd1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9RXjB/btrXhmY6NwE/iVPCwBggLjMHt6p9nEQPd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9RXjB%2FbtrXhmY6NwE%2FiVPCwBggLjMHt6p9nEQPd1%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;612&quot; height=&quot;164&quot; data-origin-width=&quot;612&quot; data-origin-height=&quot;164&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;jar파일 실행&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;java -jar 파일명.jar&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;704&quot; data-origin-height=&quot;129&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzfuA8/btrXdL6N4Kg/y6kdbtt06ALMBOk6NcJ2Z0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzfuA8/btrXdL6N4Kg/y6kdbtt06ALMBOk6NcJ2Z0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzfuA8/btrXdL6N4Kg/y6kdbtt06ALMBOk6NcJ2Z0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzfuA8%2FbtrXdL6N4Kg%2Fy6kdbtt06ALMBOk6NcJ2Z0%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;704&quot; height=&quot;129&quot; data-origin-width=&quot;704&quot; data-origin-height=&quot;129&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;swagger 확인&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 배포 되었다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;576&quot; data-origin-height=&quot;386&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blP6G8/btrXgq81QzE/VtGDx8lvRtYKILHU2x7RN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blP6G8/btrXgq81QzE/VtGDx8lvRtYKILHU2x7RN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blP6G8/btrXgq81QzE/VtGDx8lvRtYKILHU2x7RN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblP6G8%2FbtrXgq81QzE%2FVtGDx8lvRtYKILHU2x7RN0%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;576&quot; height=&quot;386&quot; data-origin-width=&quot;576&quot; data-origin-height=&quot;386&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>MountainGo</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/296</guid>
      <comments>https://gom20.tistory.com/296#entry296comment</comments>
      <pubDate>Thu, 26 Jan 2023 16:46:16 +0900</pubDate>
    </item>
    <item>
      <title>[Spring Boot][Error] gradle bootJar ':compileJava'. 에러</title>
      <link>https://gom20.tistory.com/295</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JDK 17사용.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 JDK 버전이 안맞을 때 이 문제가 발생한다던데, Java 버전 모두 동일함. 이상 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구글링 중 lombok 문제일 수도 있따고 해서 해당 방법 조치&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;해결&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AS-IS&lt;/p&gt;
&lt;pre id=&quot;code_1674718628212&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;implementation  'org.projectlombok:lombok'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TO-BE&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;java17 서포트 하는 최신버전 명시&lt;/p&gt;
&lt;pre id=&quot;code_1674718634176&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;compileOnly 'org.projectlombok:lombok:1.18.24'
annotationProcessor 'org.projectlombok:lombok:1.18.24'&lt;/code&gt;&lt;/pre&gt;</description>
      <category>MountainGo</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/295</guid>
      <comments>https://gom20.tistory.com/295#entry295comment</comments>
      <pubDate>Thu, 26 Jan 2023 16:37:21 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] EC2 Linux2 에  Spring Boot 프로젝트 배포</title>
      <link>https://gom20.tistory.com/294</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 인스턴스에서 JDK 설치&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;java 17을 쓰고 있기 때문에 아래와 같이 설치하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;java17 rpm 다운로드&lt;/h4&gt;
&lt;pre class=&quot;awk&quot;&gt;&lt;code&gt;wget https://download.oracle.com/java/17/latest/jdk-17_linux-x64_bin.rpm&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;java17 rpm 설치&lt;/h4&gt;
&lt;pre id=&quot;code_1674710217278&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo rpm -ivh jdk-17_linux-x64_bin.rpm&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;설치한 JDK 버전 선택&lt;/h4&gt;
&lt;pre id=&quot;code_1674710301755&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo alternatives --config java&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;확인&lt;/h4&gt;
&lt;pre id=&quot;code_1674710228082&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;java -version&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. Git clone&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;git설치&lt;/h4&gt;
&lt;pre id=&quot;code_1674713034187&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo install git&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;SSH키 생성&amp;nbsp;&lt;/h4&gt;
&lt;pre id=&quot;code_1674713038400&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cd ~/.ssh

ssh-keygen -t rsa -C github계정 메일&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;27&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zaEed/btrXhmxLUWE/9hRLmMNUrD1q0OJmMdZDck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zaEed/btrXhmxLUWE/9hRLmMNUrD1q0OJmMdZDck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zaEed/btrXhmxLUWE/9hRLmMNUrD1q0OJmMdZDck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzaEed%2FbtrXhmxLUWE%2F9hRLmMNUrD1q0OJmMdZDck%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;439&quot; height=&quot;27&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;27&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;공개키를 github에 등록&lt;/h4&gt;
&lt;pre id=&quot;code_1674713380346&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cat id_rsa.pub&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력된 내용을 복사하여 github ssh key 에 입력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Github setting &amp;gt; SSH and GPS Key &amp;gt; new SSH Key&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;479&quot; data-origin-height=&quot;212&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dtXDVN/btrXfNC2Ofl/ZU8bQrCP1bIDHXgVs6MNk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dtXDVN/btrXfNC2Ofl/ZU8bQrCP1bIDHXgVs6MNk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dtXDVN/btrXfNC2Ofl/ZU8bQrCP1bIDHXgVs6MNk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdtXDVN%2FbtrXfNC2Ofl%2FZU8bQrCP1bIDHXgVs6MNk0%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;479&quot; height=&quot;212&quot; data-origin-width=&quot;479&quot; data-origin-height=&quot;212&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Repository Clone SSH의 주소를 복사&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;403&quot; data-origin-height=&quot;235&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vDsck/btrXc9sW0TM/wnitGVxOKTW7sYpmPtaz3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vDsck/btrXc9sW0TM/wnitGVxOKTW7sYpmPtaz3k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vDsck/btrXc9sW0TM/wnitGVxOKTW7sYpmPtaz3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvDsck%2FbtrXc9sW0TM%2FwnitGVxOKTW7sYpmPtaz3k%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;403&quot; height=&quot;235&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;403&quot; data-origin-height=&quot;235&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;서버에서 git clone 수행&lt;/h4&gt;
&lt;pre id=&quot;code_1674713684531&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git clone SSH주소&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 빌드&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;gradlew 권한 수정&lt;/h4&gt;
&lt;pre id=&quot;code_1674719590750&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-rw-r--r-- 1 root root 8188 Jan 26 06:13 gradlew&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;sudo chmod 777 ./gradlew&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1674719622636&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-rwxrwxrwx 1 root root 8188 Jan 26 06:13 gradlew&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;빌드&lt;/h4&gt;
&lt;pre id=&quot;code_1674719701844&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo ./gradlew build&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;build/llibs 에 jar파일 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;실행&amp;nbsp;&lt;/h4&gt;
&lt;pre id=&quot;code_1674723269873&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;java -jar 파일명.jar&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 백그라운드 실행&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 실행할 경우, EC2 세션을 종료하면 서버도 종료됨.&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;백그라운드 실행&lt;/h4&gt;
&lt;pre id=&quot;code_1674725693270&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;nohup java -jar 파일명.jar &amp;amp;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;로그 확인&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;60&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mb1qC/btrXibiTxHc/NRk1XiNSYLR4F5pLfUZB01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mb1qC/btrXibiTxHc/NRk1XiNSYLR4F5pLfUZB01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mb1qC/btrXibiTxHc/NRk1XiNSYLR4F5pLfUZB01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmb1qC%2FbtrXibiTxHc%2FNRk1XiNSYLR4F5pLfUZB01%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;401&quot; height=&quot;60&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;60&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1674725720709&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cat nohup.out&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실시간 로그를 보기 위해서는 tail을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;서버 종료&lt;/h4&gt;
&lt;pre id=&quot;code_1674725767847&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;jobs
fg 해당 잡 인덱스

ctrl+c로 종료&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. 접속 확인&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;인바운드 규칙 추가&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스프링 부트 프로젝트가 8080포트를 사용하기때문에 인바운드 규칙에 추가&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1306&quot; data-origin-height=&quot;96&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/roul6/btrXcfgsyZc/ib8Zj9S5aVAqBxzUBs6Do0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/roul6/btrXcfgsyZc/ib8Zj9S5aVAqBxzUBs6Do0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/roul6/btrXcfgsyZc/ib8Zj9S5aVAqBxzUBs6Do0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Froul6%2FbtrXcfgsyZc%2Fib8Zj9S5aVAqBxzUBs6Do0%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;1306&quot; height=&quot;96&quot; data-origin-width=&quot;1306&quot; data-origin-height=&quot;96&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;swagger 접속&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;public dns ipv4주소:8080/swagger-ui.html&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 배포되었다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;561&quot; data-origin-height=&quot;218&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cb6Pkm/btrXiOnsEcu/CvJH3KBkYzlCRMjwipDEK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cb6Pkm/btrXiOnsEcu/CvJH3KBkYzlCRMjwipDEK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cb6Pkm/btrXiOnsEcu/CvJH3KBkYzlCRMjwipDEK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcb6Pkm%2FbtrXiOnsEcu%2FCvJH3KBkYzlCRMjwipDEK0%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;561&quot; height=&quot;218&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;561&quot; data-origin-height=&quot;218&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>MountainGo</category>
      <category>EC2</category>
      <category>springboot</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/294</guid>
      <comments>https://gom20.tistory.com/294#entry294comment</comments>
      <pubDate>Thu, 26 Jan 2023 15:15:31 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] EC2 Linux2에 MariaDB 설치 및 데이터 마이그레이션</title>
      <link>https://gom20.tistory.com/293</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. MariaDB 설치&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;marida db 설치&lt;/h4&gt;
&lt;pre id=&quot;code_1674705178069&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo yum install mariadb-server&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;서비스 실행&lt;/h4&gt;
&lt;pre id=&quot;code_1674705184431&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo systemctl start mariadb&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;상태확인&lt;/h4&gt;
&lt;pre id=&quot;code_1674705188725&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo systemctl status mariadb&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;관리자 비밀 번호 설정&lt;/h4&gt;
&lt;pre id=&quot;code_1674705193574&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;mysqladmin -u root -p password '비밀번호'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정 시 비밀 번호를 묻는데, 초기에는 없으므로 그냥 Enter를 치면 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;접속&lt;/h4&gt;
&lt;pre id=&quot;code_1674705198290&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;mysql -u root -p&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정한 비밀번호 입력 / 접속 완료&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;977&quot; data-origin-height=&quot;199&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/edPeCn/btrXcdO4qxf/QwYGhbqeh5difjiapu7q6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/edPeCn/btrXcdO4qxf/QwYGhbqeh5difjiapu7q6k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/edPeCn/btrXcdO4qxf/QwYGhbqeh5difjiapu7q6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FedPeCn%2FbtrXcdO4qxf%2FQwYGhbqeh5difjiapu7q6k%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;977&quot; height=&quot;199&quot; data-origin-width=&quot;977&quot; data-origin-height=&quot;199&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 데이터 베이스 생성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 베이스 생성&lt;/p&gt;
&lt;pre id=&quot;code_1674705466863&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;create database DB명&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성된 DB 확인&lt;/p&gt;
&lt;pre id=&quot;code_1674705471023&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;show databases&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;430&quot; data-origin-height=&quot;221&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCNIUP/btrXaCPCX9V/Y2drDvVCKeardu9ZKmeNHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCNIUP/btrXaCPCX9V/Y2drDvVCKeardu9ZKmeNHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCNIUP/btrXaCPCX9V/Y2drDvVCKeardu9ZKmeNHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcCNIUP%2FbtrXaCPCX9V%2FY2drDvVCKeardu9ZKmeNHk%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;338&quot; height=&quot;174&quot; data-origin-width=&quot;430&quot; data-origin-height=&quot;221&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;계정 생성&lt;/h2&gt;
&lt;pre id=&quot;code_1674706290632&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; create user '유저명'@'허용 IP' identified by '비밀번호'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;권한 부여&lt;/p&gt;
&lt;pre id=&quot;code_1674706297352&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;GRANT ALL PRIVILEGES ON [데이터베이스 이름].[허용할 테이블] TO '[계정이름]'@'[허용ip]';
FLUSH PRIVILEGES;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체 테이블 권한 줄 경우 DB명.* 로 가능&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;** 허용 ip % 로 줄경우 외부 접속 모두 허용.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 localhost는 %에 포함이 안되는지... access denied되는 문제가 있어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;localhost에서 접속하는 계정은 허용 ip를 localhost로 지정해주었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. DBeaver로 접속하기&amp;nbsp;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;AWS 보안 규칙 추가&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1323&quot; data-origin-height=&quot;90&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eiPGd8/btrXgpVKiEk/kXAkKZCXkWyCRZzimKbT3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eiPGd8/btrXgpVKiEk/kXAkKZCXkWyCRZzimKbT3K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eiPGd8/btrXgpVKiEk/kXAkKZCXkWyCRZzimKbT3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeiPGd8%2FbtrXgpVKiEk%2FkXAkKZCXkWyCRZzimKbT3K%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;1323&quot; height=&quot;90&quot; data-origin-width=&quot;1323&quot; data-origin-height=&quot;90&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;DBeaver 실행&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Create Connection &amp;gt; MariaDB 선택&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;242&quot; data-origin-height=&quot;447&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EtvCo/btrXaDOKGfL/pwpj4nx0UnCMew1czI2Pl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EtvCo/btrXaDOKGfL/pwpj4nx0UnCMew1czI2Pl0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EtvCo/btrXaDOKGfL/pwpj4nx0UnCMew1czI2Pl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEtvCo%2FbtrXaDOKGfL%2Fpwpj4nx0UnCMew1czI2Pl0%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;242&quot; height=&quot;447&quot; data-origin-width=&quot;242&quot; data-origin-height=&quot;447&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인스턴스의 public DNS Ip4v 주소로 접속&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;h2 data-ke-size=&quot;size26&quot;&gt;4. DBeaver 로컬 DB에서 클라우드 DB로 데이터 이관&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;로컬 DB에서 테이블 선택한 후, 우클릭 &amp;gt; 데이터 내보내기&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;820&quot; data-origin-height=&quot;628&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhZJRS/btrXgH9OtIg/XmRkXzCwShltrIUmRRgcek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhZJRS/btrXgH9OtIg/XmRkXzCwShltrIUmRRgcek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhZJRS/btrXgH9OtIg/XmRkXzCwShltrIUmRRgcek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhZJRS%2FbtrXgH9OtIg%2FXmRkXzCwShltrIUmRRgcek%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;742&quot; height=&quot;568&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;820&quot; data-origin-height=&quot;628&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;타겟DB 지정 (이전에 연결한 AWS DB 컨테이너를 지정한다)&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;812&quot; data-origin-height=&quot;620&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4D7IV/btrXgw1HfsR/PCrYFtBetACxYzk2Z4EMDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4D7IV/btrXgw1HfsR/PCrYFtBetACxYzk2Z4EMDk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4D7IV/btrXgw1HfsR/PCrYFtBetACxYzk2Z4EMDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4D7IV%2FbtrXgw1HfsR%2FPCrYFtBetACxYzk2Z4EMDk%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;812&quot; height=&quot;620&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;812&quot; data-origin-height=&quot;620&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;기타 설정 후, 최종 confirm&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테이블이 존재하지 않으면 자동 생성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 테이블은 DDL로 별도 생성하고 데이터만 옮기는 것을 추천한다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1183&quot; data-origin-height=&quot;622&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dMJwDg/btrXaBQ4V1A/sgKRW9KGyuIygHfrTrKLtk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dMJwDg/btrXaBQ4V1A/sgKRW9KGyuIygHfrTrKLtk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dMJwDg/btrXaBQ4V1A/sgKRW9KGyuIygHfrTrKLtk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdMJwDg%2FbtrXaBQ4V1A%2FsgKRW9KGyuIygHfrTrKLtk%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;807&quot; height=&quot;424&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1183&quot; data-origin-height=&quot;622&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>MountainGo</category>
      <category>EC2</category>
      <category>Linux</category>
      <category>MariaDB</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/293</guid>
      <comments>https://gom20.tistory.com/293#entry293comment</comments>
      <pubDate>Thu, 26 Jan 2023 12:54:04 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] EC2 Linux2에 Redis 설치</title>
      <link>https://gom20.tistory.com/292</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #383a42;&quot;&gt;&lt;span style=&quot;background-color: #fafafa;&quot;&gt;1. 사전 작업&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #383a42;&quot;&gt;&lt;span style=&quot;background-color: #fafafa;&quot;&gt;패키지 최신 업데이트&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1674703356734&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo yum update&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #383a42;&quot;&gt;&lt;span style=&quot;background-color: #fafafa;&quot;&gt;gcc make 설치&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1674703374212&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo yum install gcc make&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #383a42;&quot;&gt;&lt;span style=&quot;background-color: #fafafa;&quot;&gt;redis 포트 열어주기&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #383a42;&quot;&gt;&lt;span style=&quot;background-color: #fafafa;&quot;&gt;AWS 인스턴스 적용 보안그룹에 아래 규칙 추가&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1306&quot; data-origin-height=&quot;93&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOuxLe/btrXe9ZxHNs/Rg1APN6XKtPU3Zo0pl6CiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOuxLe/btrXe9ZxHNs/Rg1APN6XKtPU3Zo0pl6CiK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOuxLe/btrXe9ZxHNs/Rg1APN6XKtPU3Zo0pl6CiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOuxLe%2FbtrXe9ZxHNs%2FRg1APN6XKtPU3Zo0pl6CiK%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;1306&quot; height=&quot;93&quot; data-origin-width=&quot;1306&quot; data-origin-height=&quot;93&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. redis 설치&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;redis설치할 폴더 생성&lt;/h4&gt;
&lt;pre id=&quot;code_1674703382814&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo mkdir ~/redis&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;redis 설치&lt;/h4&gt;
&lt;pre id=&quot;code_1674703386902&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo wget http://download.redis.io/redis-stable.tar.gz&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;압축 해제&lt;/h4&gt;
&lt;pre id=&quot;code_1674703391398&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo tar zxvf redis-stable.tar.gz&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;885&quot; data-origin-height=&quot;49&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bN1J4T/btrXaZXRF58/AWfirkGJeGmpR1DcnaRgmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bN1J4T/btrXaZXRF58/AWfirkGJeGmpR1DcnaRgmK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bN1J4T/btrXaZXRF58/AWfirkGJeGmpR1DcnaRgmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbN1J4T%2FbtrXaZXRF58%2FAWfirkGJeGmpR1DcnaRgmK%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;885&quot; height=&quot;49&quot; data-origin-width=&quot;885&quot; data-origin-height=&quot;49&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;컴파일&lt;/h4&gt;
&lt;pre id=&quot;code_1674703396856&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo cd redis-stable
sudo make&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;redis-server, redis-cli가 /usr/local/bin 경로에 생성&lt;/p&gt;
&lt;pre id=&quot;code_1674703402932&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo make install&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. redis 설정&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;디렉토리 생성&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정파일 저장, 데이터 저장할 폴더&lt;/p&gt;
&lt;pre id=&quot;code_1674703431012&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo mkdir /etc/redis
sudo mkdir /var/lib/redis&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;설정파일 복사&lt;/h4&gt;
&lt;pre id=&quot;code_1674703434373&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo cp redis.conf /etc/redis&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;설정파일 수정&lt;/h4&gt;
&lt;pre id=&quot;code_1674703442347&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo vi /etc/redis/redis.conf

daemonize yes
dir /var/lib/redis
logfile /var/log/redis.log&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Redis 백그라운드 실행 스크립트&lt;/h4&gt;
&lt;pre id=&quot;code_1674703448290&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo wget https://raw.githubusercontent.com/saxenap/install-redis-amazon-linux-centos/master/redis-server
sudo mv redis-server /etc/init.d
sudo chmod 755 /etc/init.d/redis-server&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #383a42;&quot;&gt;&lt;span style=&quot;background-color: #fafafa;&quot;&gt;Auto Enable 설정&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1674703467607&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo chkconfig --add redis-server
sudo chkconfig --level 345 redis-server on&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #383a42;&quot;&gt;&lt;span style=&quot;background-color: #fafafa;&quot;&gt;redis 실행&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1674703472517&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo service redis-server start&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;실행 확인&lt;/h4&gt;
&lt;pre id=&quot;code_1674703476462&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;reds-cli ping&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;실행 중지&lt;/h4&gt;
&lt;pre id=&quot;code_1674703780065&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;redis-cli shutdown&lt;/code&gt;&lt;/pre&gt;</description>
      <category>MountainGo</category>
      <category>EC2</category>
      <category>Linux</category>
      <category>redis</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/292</guid>
      <comments>https://gom20.tistory.com/292#entry292comment</comments>
      <pubDate>Thu, 26 Jan 2023 12:26:29 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] EC2 Linux root 계정 활성화</title>
      <link>https://gom20.tistory.com/291</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;EC2 인스턴스 생성 후, putty로 로그인 시 root를 입력하면 아래와 같은 메시지가 표시된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;637&quot; data-origin-height=&quot;83&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dlKNDZ/btrW9qhyUhV/MyffZGq2ORrnKzdZKxrGc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dlKNDZ/btrW9qhyUhV/MyffZGq2ORrnKzdZKxrGc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dlKNDZ/btrW9qhyUhV/MyffZGq2ORrnKzdZKxrGc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdlKNDZ%2FbtrW9qhyUhV%2FMyffZGq2ORrnKzdZKxrGc1%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;668&quot; height=&quot;87&quot; data-origin-width=&quot;637&quot; data-origin-height=&quot;83&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. ec2-user로 로그인&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;743&quot; data-origin-height=&quot;179&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cIZi8Y/btrXanLGSqk/QZfO3ul0XAH2VMsJKzrQbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cIZi8Y/btrXanLGSqk/QZfO3ul0XAH2VMsJKzrQbK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cIZi8Y/btrXanLGSqk/QZfO3ul0XAH2VMsJKzrQbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcIZi8Y%2FbtrXanLGSqk%2FQZfO3ul0XAH2VMsJKzrQbK%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;673&quot; height=&quot;162&quot; data-origin-width=&quot;743&quot; data-origin-height=&quot;179&quot;/&gt;&lt;/span&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;2. root 계정 비밀 번호 설정&lt;/p&gt;
&lt;pre id=&quot;code_1674698755087&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo passwd root&lt;/code&gt;&lt;/pre&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. sshd_config 파일 수정&lt;/p&gt;
&lt;pre id=&quot;code_1674698835250&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo vi /etc/ssh/sshd_config&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;#PermitRootLogin yes&amp;nbsp;항목의 # (주석) 제거&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;:wq 로 vi 종료&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;4. root 로 로그인&lt;/p&gt;
&lt;pre id=&quot;code_1674699261035&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;su - root&lt;/code&gt;&lt;/pre&gt;</description>
      <category>MountainGo</category>
      <category>EC2</category>
      <category>Root</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/291</guid>
      <comments>https://gom20.tistory.com/291#entry291comment</comments>
      <pubDate>Thu, 26 Jan 2023 11:15:01 +0900</pubDate>
    </item>
    <item>
      <title>[Git] 특정 파일 히스토리 삭제</title>
      <link>https://gom20.tistory.com/290</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;public repository에 민감 정보가 포함된 파일 이력이 남아서,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;강제로 해당 파일의 히스토리를 삭제할 필요가 있어서 찾아 보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;git local repository로 이동하여 cmd창을 열어 아래 명령어를 실행한다. (참고로 window os)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1674643422248&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git filter-branch --force --index-filter &quot;git rm --cached --ignore-unmatch &amp;lt;파일 경로&amp;gt;&quot; --prune-empty --tag-name-filter cat -- --all&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예) src/main/resources/application.properties&lt;/p&gt;
&lt;pre id=&quot;code_1674643470567&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git filter-branch --force --index-filter &quot;git rm --cached --ignore-unmatch src/main/resources/application.properties&quot; --prune-empty --tag-name-filter cat -- --all&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;강제 push하여 히스토리 적용&lt;/p&gt;
&lt;pre id=&quot;code_1674643536311&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git push origin main --force&lt;/code&gt;&lt;/pre&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;</description>
      <category>MountainGo</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/290</guid>
      <comments>https://gom20.tistory.com/290#entry290comment</comments>
      <pubDate>Wed, 25 Jan 2023 19:48:01 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 외벽 점검 (Python)</title>
      <link>https://gom20.tistory.com/289</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/60062?language=python3&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/60062?language=python3&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1671496611987&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;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/60062?language=python3&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/boUeYz/hyQWw8lHSB/bxgj16TkM8DDLZcHXsypCK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/tOVFd/hyQWzcVtil/SJ8S3K4O0xOqFjelkYY9Uk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/60062?language=python3&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/60062?language=python3&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/boUeYz/hyQWw8lHSB/bxgj16TkM8DDLZcHXsypCK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/tOVFd/hyQWzcVtil/SJ8S3K4O0xOqFjelkYY9Uk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;programmers.co.kr&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이 &amp;amp; &lt;/b&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1671496623406&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from itertools import permutations
def solution(n, weak, dist):
    answer = len(dist) + 1
    # 취약점 길이를 두배로 늘리기
    weak_len = len(weak)
    for i in range(weak_len):
        weak.append(weak[i] + n)
    
    # 친구의 순열을 뽑는다.
    friends_list = list(permutations(dist, len(dist))) 
    
    # 취약점 시작점 모든 경우의 수
    for start in range(weak_len):
        # 친구 순열 모든 경우의 수
        for friends in friends_list:
            # start 취약점에 친구 한명 놓기 
            count = 1
            position = weak[start] + friends[count-1]
            
            for index in range(start, start + weak_len):
                # 현재 친구 포지션이 모든 취약점을 다 커버할 수 있는지 체크
                if position &amp;lt; weak[index]:
                    # 다 커버가 안된다면
                    count += 1
                    if count &amp;gt; len(dist):
                        break
                    # 커버 안되는 취약점에 다른 친구 놓기
                    position = weak[index] + friends[count-1]
            
            answer = min(answer, count)
    if answer &amp;gt; len(dist):
        return -1

    return answer&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/Programmers</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/289</guid>
      <comments>https://gom20.tistory.com/289#entry289comment</comments>
      <pubDate>Tue, 20 Dec 2022 09:37:09 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 2887] 행성 터널 (Python)</title>
      <link>https://gom20.tistory.com/288</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2887&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/2887&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1669163802302&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;2887번: 행성 터널&quot; data-og-description=&quot;첫째 줄에 행성의 개수 N이 주어진다. (1 &amp;le; N &amp;le; 100,000) 다음 N개 줄에는 각 행성의 x, y, z좌표가 주어진다. 좌표는 -109보다 크거나 같고, 109보다 작거나 같은 정수이다. 한 위치에 행성이 두 개 이&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/2887&quot; data-og-url=&quot;https://www.acmicpc.net/problem/2887&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/6S1Zs/hyQFeT1MMY/UO44km8Zv6dEKtTvVpDbYK/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/2887&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/2887&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/6S1Zs/hyQFeT1MMY/UO44km8Zv6dEKtTvVpDbYK/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;2887번: 행성 터널&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫째 줄에 행성의 개수 N이 주어진다. (1 &amp;le; N &amp;le; 100,000) 다음 N개 줄에는 각 행성의 x, y, z좌표가 주어진다. 좌표는 -109보다 크거나 같고, 109보다 작거나 같은 정수이다. 한 위치에 행성이 두 개 이&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;크루스컬로 풀면 될 것 같은데&amp;nbsp;간선 정보가 없다.&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;&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;x, y, z 각 좌표와 노드 번호를 저장 후 좌표 값 오름차순으로 정렬&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좌표 별로 한쌍 씩 묶어서 비용과 노드를 edges 리스트에 저장&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;edges 리스트 오름차순으로 정렬. 여기에는 (N-1)*3 개수의 간선이 저장되어 있다.&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1669164154448&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import sys
input = sys.stdin.readline

n = int(input())
arr = [[0]*3 for _ in range(n)]

parent = [0]*n
for i in range(n):
    parent[i] = i

def find_parent(parent, x):
    if parent[x] != x:
        parent[x] = find_parent(parent, parent[x])
    return parent[x]

def union(parent, a, b):
    a = find_parent(parent, a)
    b = find_parent(parent, b)
    if a &amp;lt; b:
        parent[b] = a
    else:
        parent[a] = b

for i in range(n):
    data = list(map(int, input().split()))
    for j in range(3):
        arr[i][j] = data[j]

arr_x = []
arr_y = []
arr_z = []

for i in range(n):
    for j in range(3):
        if j == 0:
            arr_x.append((arr[i][j], i))
        if j == 1:
            arr_y.append((arr[i][j], i))
        if j == 2:
            arr_z.append((arr[i][j], i))

arr_x.sort()
arr_y.sort()
arr_z.sort()

edges = []
for i in range(1, n):
    edges.append((abs(arr_x[i][0] - arr_x[i - 1][0]), arr_x[i][1], arr_x[i-1][1]))
    edges.append((abs(arr_y[i][0] - arr_y[i - 1][0]), arr_y[i][1], arr_y[i-1][1]))
    edges.append((abs(arr_z[i][0] - arr_z[i - 1][0]), arr_z[i][1], arr_z[i-1][1]))

edges.sort()

minimum_cost = 0
for edge in edges:
    cost, a, b, = edge
    if find_parent(parent, a) != find_parent(parent, b):
        union(parent, a, b)
        minimum_cost += cost

print(minimum_cost)&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/BOJ</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/288</guid>
      <comments>https://gom20.tistory.com/288#entry288comment</comments>
      <pubDate>Wed, 23 Nov 2022 09:42:43 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 11404] 플로이드 (Python)</title>
      <link>https://gom20.tistory.com/287</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/11404&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/11404&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1669096567289&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;11404번: 플로이드&quot; data-og-description=&quot;첫째 줄에 도시의 개수 n이 주어지고 둘째 줄에는 버스의 개수 m이 주어진다. 그리고 셋째 줄부터 m+2줄까지 다음과 같은 버스의 정보가 주어진다. 먼저 처음에는 그 버스의 출발 도시의 번호가 &quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/11404&quot; data-og-url=&quot;https://www.acmicpc.net/problem/11404&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cpMW9c/hyQE1fsmo8/2jVxkM3TWKFUPMqOHTztYk/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/11404&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/11404&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cpMW9c/hyQE1fsmo8/2jVxkM3TWKFUPMqOHTztYk/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;11404번: 플로이드&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫째 줄에 도시의 개수 n이 주어지고 둘째 줄에는 버스의 개수 m이 주어진다. 그리고 셋째 줄부터 m+2줄까지 다음과 같은 버스의 정보가 주어진다. 먼저 처음에는 그 버스의 출발 도시의 번호가&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;floyd 알고리즘&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1669096575553&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;n = int(input())
m = int(input())

arr = [[1e9]*(n+1) for _ in range(n+1)]
for i in range(1, n+1):
    for j in range(1, n+1):
        if i == j:
            arr[i][j] = 0

for _ in range(m):
    i, j, cost = map(int, input().split())
    arr[i][j] = min(arr[i][j], cost)

for k in range(1 ,n+1):
    for i in range(1, n+1):
        for j in range(1, n+1):
            arr[i][j] = min(arr[i][j], arr[i][k] + arr[k][j])

for i in range(1, n+1):

    for j in range(1, n+1):
        if arr[i][j] == 1e9:
            arr[i][j] = 0
        print(arr[i][j], end= ' ')
    print()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category> Problem Solving/BOJ</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/287</guid>
      <comments>https://gom20.tistory.com/287#entry287comment</comments>
      <pubDate>Tue, 22 Nov 2022 14:57:07 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 18353] 병사 배치하기 (Python)</title>
      <link>https://gom20.tistory.com/286</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/18353&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/18353&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1669086281872&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;18353번: 병사 배치하기&quot; data-og-description=&quot;첫째 줄에 N이 주어진다. (1 &amp;le;&amp;nbsp;N&amp;nbsp;&amp;le; 2,000) 둘째 줄에 각 병사의 전투력이 공백을 기준으로 구분되어 차례대로 주어진다. 각 병사의 전투력은 10,000,000보다 작거나 같은 자연수이다.&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/18353&quot; data-og-url=&quot;https://www.acmicpc.net/problem/18353&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/c19Tyb/hyQE01Mw50/jhNhl23h89AGRkVN9Unzq0/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/18353&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/18353&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/c19Tyb/hyQE01Mw50/jhNhl23h89AGRkVN9Unzq0/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;18353번: 병사 배치하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫째 줄에 N이 주어진다. (1 &amp;le;&amp;nbsp;N&amp;nbsp;&amp;le; 2,000) 둘째 줄에 각 병사의 전투력이 공백을 기준으로 구분되어 차례대로 주어진다. 각 병사의 전투력은 10,000,000보다 작거나 같은 자연수이다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LIS 알고리즘 사용.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DP방식으로 이중 For문 사용하여 구현&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gom20.tistory.com/91&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://gom20.tistory.com/91&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1669086374259&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;[Algorithm] LIS 알고리즘 (최장증가수열 알고리즘)&quot; data-og-description=&quot;LIS 알고리즘이란? LIS 알고리즘 (Longest Increasing Subsequence Algorithm) 은 최장증가수열 알고리즘으로 증가하는 원소들의 가장 긴 부분집합을 찾는 알고리즘이다. 풀이 1. DP로 풀기 시간 복잡도 O(N^2) 이&quot; data-og-host=&quot;gom20.tistory.com&quot; data-og-source-url=&quot;https://gom20.tistory.com/91&quot; data-og-url=&quot;https://gom20.tistory.com/91&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dq01ML/hyQFfdySc8/Vez03AYct8Ia65AOsgqKpk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/UDmD0/hyQE6gCgS2/KvoatAtJsgLkLm1QhqrCQ0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://gom20.tistory.com/91&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://gom20.tistory.com/91&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dq01ML/hyQFfdySc8/Vez03AYct8Ia65AOsgqKpk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/UDmD0/hyQE6gCgS2/KvoatAtJsgLkLm1QhqrCQ0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&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;[Algorithm] LIS 알고리즘 (최장증가수열 알고리즘)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;LIS 알고리즘이란? LIS 알고리즘 (Longest Increasing Subsequence Algorithm) 은 최장증가수열 알고리즘으로 증가하는 원소들의 가장 긴 부분집합을 찾는 알고리즘이다. 풀이 1. DP로 풀기 시간 복잡도 O(N^2) 이&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;gom20.tistory.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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre class=&quot;vim&quot;&gt;&lt;code&gt;n = int(input())

arr = list(map(int, input().split()))
arr.reverse()
# print(arr)

dp = [1]*n

for i in range(1, n):
    for j in range(0, i):
        if arr[i] &amp;gt; arr[j]:
            dp[i] = max(dp[i], 1 + dp[j])

print(n-max(dp))

&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/BOJ</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/286</guid>
      <comments>https://gom20.tistory.com/286#entry286comment</comments>
      <pubDate>Tue, 22 Nov 2022 12:04:44 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 1715] 카드 정렬하기 (Python)</title>
      <link>https://gom20.tistory.com/285</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1715&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/1715&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1668844295302&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;1715번: 카드 정렬하기&quot; data-og-description=&quot;정렬된 두 묶음의 숫자 카드가 있다고 하자. 각 묶음의 카드의 수를 A, B라 하면 보통 두 묶음을 합쳐서 하나로 만드는 데에는 A+B 번의 비교를 해야 한다. 이를테면, 20장의 숫자 카드 묶음과 30장&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/1715&quot; data-og-url=&quot;https://www.acmicpc.net/problem/1715&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cqkluL/hyQBRygIbQ/q602Ku06AInkOcm5kfkZy1/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/1715&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/1715&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cqkluL/hyQBRygIbQ/q602Ku06AInkOcm5kfkZy1/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;1715번: 카드 정렬하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;정렬된 두 묶음의 숫자 카드가 있다고 하자. 각 묶음의 카드의 수를 A, B라 하면 보통 두 묶음을 합쳐서 하나로 만드는 데에는 A+B 번의 비교를 해야 한다. 이를테면, 20장의 숫자 카드 묶음과 30장&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초반에는 작은 수끼리 묶으면 될거라 생각해서 단순 sort하여 더하는 코드를 작성하였다.&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;왜냐면 동일한 숫자 카드가 존재할 수 있기 때문이다.&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;3 3 3 3&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4개의 숫자카드를 순차적으로 더해나간다면&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3+3 = 6&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6+3 = 9&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;9+3 = 12&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;27로 오답이 나온다.&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;이 경우&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3+3 = 6&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3+3 = 6&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6+6 = 12&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;24가 정답이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 숫자 카드를 묶을때마다 sort를 다시 해줘야 한다는건데&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;
&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1668844457227&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import heapq

n = int(input())
q = []
for _ in range(n):
    heapq.heappush(q, int(input()))

result = 0
while len(q) &amp;gt;= 2:
    prev = heapq.heappop(q)
    cur = heapq.heappop(q)
    # print(prev, cur)
    result += prev + cur
    new = prev + cur
    heapq.heappush(q, new)

print(result)&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/BOJ</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/285</guid>
      <comments>https://gom20.tistory.com/285#entry285comment</comments>
      <pubDate>Sat, 19 Nov 2022 16:54:23 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 18310] 안테나 (Python)</title>
      <link>https://gom20.tistory.com/284</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/18310&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/18310&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1668840126627&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;18310번: 안테나&quot; data-og-description=&quot;첫째 줄에 집의 수 N이 자연수로 주어진다.&amp;nbsp;(1&amp;le;N&amp;le;200,000) 둘째 줄에 N채의 집에 위치가 공백을 기준으로 구분되어 1이상 100,000이하의 자연수로 주어진다.&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/18310&quot; data-og-url=&quot;https://www.acmicpc.net/problem/18310&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cbeXXS/hyQBYEdiak/dVBAUq94aT0g4OKMof1wuk/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480,https://scrap.kakaocdn.net/dn/d5FE1k/hyQB2zRiIV/LXnmKZAtgHxsbdZkIFfzH0/img.jpg?width=1272&amp;amp;height=239&amp;amp;face=0_0_1272_239&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/18310&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/18310&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cbeXXS/hyQBYEdiak/dVBAUq94aT0g4OKMof1wuk/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480,https://scrap.kakaocdn.net/dn/d5FE1k/hyQB2zRiIV/LXnmKZAtgHxsbdZkIFfzH0/img.jpg?width=1272&amp;amp;height=239&amp;amp;face=0_0_1272_239');&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;18310번: 안테나&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫째 줄에 집의 수 N이 자연수로 주어진다.&amp;nbsp;(1&amp;le;N&amp;le;200,000) 둘째 줄에 N채의 집에 위치가 공백을 기준으로 구분되어 1이상 100,000이하의 자연수로 주어진다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1668840116800&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;n = int(input())
data = list(map(int, input().split()))

data.sort()

if n == 1:
    print(data[0])
elif n % 2 == 0:
    print(data[int(n//2-1)])
else:
    print(data[int(n//2)])&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/BOJ</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/284</guid>
      <comments>https://gom20.tistory.com/284#entry284comment</comments>
      <pubDate>Sat, 19 Nov 2022 15:42:52 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 10825] 국영수 (Python)</title>
      <link>https://gom20.tistory.com/283</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/10825&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/10825&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1668839152615&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;10825번: 국영수&quot; data-og-description=&quot;첫째 줄에 도현이네 반의 학생의 수 N (1 &amp;le; N &amp;le; 100,000)이 주어진다. 둘째 줄부터 한 줄에 하나씩 각 학생의 이름, 국어, 영어, 수학 점수가 공백으로 구분해 주어진다. 점수는 1보다 크거나 같고, 1&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/10825&quot; data-og-url=&quot;https://www.acmicpc.net/problem/10825&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b9N5LK/hyQBW7suDo/S5UhYDk0EmNg5jigGbxOSK/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/10825&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/10825&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b9N5LK/hyQBW7suDo/S5UhYDk0EmNg5jigGbxOSK/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;10825번: 국영수&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫째 줄에 도현이네 반의 학생의 수 N (1 &amp;le; N &amp;le; 100,000)이 주어진다. 둘째 줄부터 한 줄에 하나씩 각 학생의 이름, 국어, 영어, 수학 점수가 공백으로 구분해 주어진다. 점수는 1보다 크거나 같고, 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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Python 다중 정렬&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sort 라이브러리 사용&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;labmda로 튜플의 몇 번째 원소부터 정렬할 지 명시&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1668839137560&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;n = int(input())
a = []
for _ in range(n):
    data = list(input().split())
    a.append((data[0], int(data[1]), int(data[2]), int(data[3])))

result = sorted(a, key = lambda x: (-x[1], x[2], -x[3], x[0]))
for r in result:
    print(r[0])&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/BOJ</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/283</guid>
      <comments>https://gom20.tistory.com/283#entry283comment</comments>
      <pubDate>Sat, 19 Nov 2022 15:26:32 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 18428] 감시 피하기 (Python)</title>
      <link>https://gom20.tistory.com/282</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/18428&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/18428&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1668826712993&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;18428번: 감시 피하기&quot; data-og-description=&quot;NxN&amp;nbsp;크기의 복도가 있다. 복도는 1x1&amp;nbsp;크기의 칸으로 나누어지며, 특정한 위치에는 선생님, 학생, 혹은 장애물이 위치할 수 있다. 현재 몇 명의 학생들은 수업시간에 몰래 복도로 빠져나왔는데, 복&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/18428&quot; data-og-url=&quot;https://www.acmicpc.net/problem/18428&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/fTTx7/hyQBRSw0TR/U33z99NhoSaEvt4t0J7lhk/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480,https://scrap.kakaocdn.net/dn/bSdUlJ/hyQDvtxauR/gAh4KphXvnBt5LtzRRzHf0/img.png?width=703&amp;amp;height=621&amp;amp;face=0_0_703_621,https://scrap.kakaocdn.net/dn/f80Hn/hyQBXFbMAj/FyteuYwf49LjD2sc23eMPK/img.png?width=701&amp;amp;height=618&amp;amp;face=0_0_701_618&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/18428&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/18428&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/fTTx7/hyQBRSw0TR/U33z99NhoSaEvt4t0J7lhk/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480,https://scrap.kakaocdn.net/dn/bSdUlJ/hyQDvtxauR/gAh4KphXvnBt5LtzRRzHf0/img.png?width=703&amp;amp;height=621&amp;amp;face=0_0_703_621,https://scrap.kakaocdn.net/dn/f80Hn/hyQBXFbMAj/FyteuYwf49LjD2sc23eMPK/img.png?width=701&amp;amp;height=618&amp;amp;face=0_0_701_618');&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;18428번: 감시 피하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;NxN&amp;nbsp;크기의 복도가 있다. 복도는 1x1&amp;nbsp;크기의 칸으로 나누어지며, 특정한 위치에는 선생님, 학생, 혹은 장애물이 위치할 수 있다. 현재 몇 명의 학생들은 수업시간에 몰래 복도로 빠져나왔는데, 복&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;combnation으로 3개의 장애물 좌표 조합 구하기&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장애물 설치 후 teacher 위치 좌표 반복문 돌려서 dfs 실행&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;감시영역 내의 학생수 count&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;dfs 종료 후, 감시된 학생 수가 0명이면 'YES' 출력하고 프로그램 종료&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1668826796339&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from itertools import combinations

n = int(input())
arr = []
teachers = []
students = []
candidates = []
for _ in range(n):
    data = list(input().split())
    arr.append(data)

for i in range(n):
    for j in range(n):
        if arr[i][j] == 'T':
            teachers.append((i, j))
        elif arr[i][j] == 'X':
            candidates.append((i, j))
        else:
            students.append((i, j))


dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]

monitored_count = 0

def dfs(x, y, d):
    # print(x, y)
    global monitored_count
    if arr[x][y] == 'X' or arr[x][y] == 'S':
        if arr[x][y] == 'S':
            arr[x][y] = 'X'
            monitored_count += 1
        nx = x + dx[d]
        ny = y + dy[d]
        if nx &amp;lt; 0 or ny &amp;lt; 0 or nx &amp;gt;= n or ny &amp;gt;= n:
            return
        dfs(nx, ny, d)

obstacles_list = list(combinations(candidates, 3))
for obstacles in obstacles_list:
    # 장애물 설치
    monitored_count = 0

    for obstacle in obstacles:
        ox, oy = obstacle
        arr[ox][oy] = 'O'

    # print(arr)

    for teacher in teachers:
        tx, ty = teacher
        # print('tx, ty', tx, ty)
        for d in range(4):
            nx = tx + dx[d]
            ny= ty + dy[d]
            # print('nx,ny', nx,ny)
            if nx &amp;lt; 0 or ny &amp;lt; 0 or nx &amp;gt;= n or ny &amp;gt;= n:
                continue
            dfs(nx, ny, d)

    if monitored_count == 0:
        print('YES')
        exit(0)

    # 원상 복구
    for obstacle in obstacles:
        ox, oy = obstacle
        arr[ox][oy] = 'X'
    for student in students:
        sx, sy = student
        arr[sx][sy] = 'S'

print('NO')&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/BOJ</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/282</guid>
      <comments>https://gom20.tistory.com/282#entry282comment</comments>
      <pubDate>Sat, 19 Nov 2022 12:00:07 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ14888] 연산자 끼워 넣기 (Python)</title>
      <link>https://gom20.tistory.com/281</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/14888&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/14888&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1668673846058&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;14888번: 연산자 끼워넣기&quot; data-og-description=&quot;첫째 줄에 수의 개수 N(2 &amp;le; N &amp;le; 11)가 주어진다. 둘째 줄에는 A1, A2, ..., AN이 주어진다. (1 &amp;le; Ai &amp;le; 100) 셋째 줄에는 합이 N-1인 4개의 정수가 주어지는데, 차례대로 덧셈(+)의 개수, 뺄셈(-)의 개수,&amp;nbsp;&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/14888&quot; data-og-url=&quot;https://www.acmicpc.net/problem/14888&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bf4lnp/hyQBdBxdAc/NPSqxhDeFT18Y2K1Zftx5k/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/14888&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/14888&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bf4lnp/hyQBdBxdAc/NPSqxhDeFT18Y2K1Zftx5k/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;14888번: 연산자 끼워넣기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫째 줄에 수의 개수 N(2 &amp;le; N &amp;le; 11)가 주어진다. 둘째 줄에는 A1, A2, ..., AN이 주어진다. (1 &amp;le; Ai &amp;le; 100) 셋째 줄에는 합이 N-1인 4개의 정수가 주어지는데, 차례대로 덧셈(+)의 개수, 뺄셈(-)의 개수,&amp;nbsp;&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1668673867973&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;n = int(input())
nums = list(map(int, input().split()))
opers = list(map(int, input().split())) # +,-,*,/


max_result = -1e9
min_result = 1e9

def dfs(nums, opers, total, k, s):
    global n, max_result, min_result
    if k == n:
        # print(s, total)
        max_result = max(total, max_result)
        min_result = min(total, min_result)

    for i in range(len(opers)):
        temp = ''
        temp_total = total
        if opers[i] &amp;gt; 0:
            if i == 0:
                temp = s + '+' + str(nums[k])
                temp_total += nums[k]
            if i == 1:
                temp = s + '-' + str(nums[k])
                temp_total -= nums[k]
            if i == 2:
                temp = s + '*' + str(nums[k])
                temp_total *= nums[k]
            if i == 3:
                temp = s + '/' + str(nums[k])
                if temp_total &amp;lt; 0:
                    temp_total = abs(temp_total)
                    temp_total = int(temp_total//nums[k])
                    temp_total *= -1
                else:
                    temp_total = int(temp_total // nums[k])
            opers[i] -= 1
            # print(opers)
            dfs(nums, opers, temp_total, k+1, temp)
            opers[i] += 1

dfs(nums, opers, nums[0], 1, str(nums[0]))

print(max_result)
print(min_result)&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/BOJ</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/281</guid>
      <comments>https://gom20.tistory.com/281#entry281comment</comments>
      <pubDate>Thu, 17 Nov 2022 17:31:14 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 괄호 변환 (Python)</title>
      <link>https://gom20.tistory.com/280</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/60058?language=python3&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/60058&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1668671702441&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;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/60058?language=python3&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/GDH3N/hyQB2Zp8Y7/iAO6N54CIKhdrfcd7uNknk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/BhUga/hyQA81jtv8/JiLYVh2kol6lVOVQmNF4c0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/60058?language=python3&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/60058?language=python3&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/GDH3N/hyQB2Zp8Y7/iAO6N54CIKhdrfcd7uNknk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/BhUga/hyQA81jtv8/JiLYVh2kol6lVOVQmNF4c0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;pre class=&quot;lsl&quot;&gt;&lt;code&gt;1. 입력이 빈 문자열인 경우, 빈 문자열을 반환합니다. 
2. 문자열 w를 두 &quot;균형잡힌 괄호 문자열&quot; u, v로 분리합니다. 단, u는 &quot;균형잡힌 괄호 문자열&quot;로 더 이상 분리할 수 없어야 하며, v는 빈 문자열이 될 수 있습니다. 
3. 문자열 u가 &quot;올바른 괄호 문자열&quot; 이라면 문자열 v에 대해 1단계부터 다시 수행합니다. 
  3-1. 수행한 결과 문자열을 u에 이어 붙인 후 반환합니다. 
4. 문자열 u가 &quot;올바른 괄호 문자열&quot;이 아니라면 아래 과정을 수행합니다. 
  4-1. 빈 문자열에 첫 번째 문자로 '('를 붙입니다. 
  4-2. 문자열 v에 대해 1단계부터 재귀적으로 수행한 결과 문자열을 이어 붙입니다. 
  4-3. ')'를 다시 붙입니다. 
  4-4. u의 첫 번째와 마지막 문자를 제거하고, 나머지 문자열의 괄호 방향을 뒤집어서 뒤에 붙입니다. 
  4-5. 생성된 문자열을 반환합니다.&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1668671730833&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def valanced_str(w):
    if w == '':
        return ''

    count = {'(': 0, ')': 0}
    u, v = '', ''
    for i in range(len(w)):
        count[w[i]] += 1
        u += w[i]
        if count['('] == count[')']:
            v = w[i+1:] if i &amp;lt; len(w) else ''      
            break
    
    if right_str(u):
        return u + valanced_str(v)
    else: 
        temp = '('
        temp += valanced_str(v)
        temp += ')'
        for us in u[1:-1]:
            if us == ')':
                temp += '('
            else:
                temp += ')'
        return temp
    
def right_str(u):
    stack = []
    for us in u:
        if us == '(':
            stack.append(us)
        else:
            if len(stack) == 0:
                return False
            stack.pop()
    
    if len(stack) == 0:
        return True
    else:
        return False
    

def solution(p):
    answer = ''
    if p == '':
        return p
    
    answer = valanced_str(p)
        
    return answer&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/Programmers</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/280</guid>
      <comments>https://gom20.tistory.com/280#entry280comment</comments>
      <pubDate>Thu, 17 Nov 2022 16:55:47 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 18405] 경쟁적 전염 (Python)</title>
      <link>https://gom20.tistory.com/279</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/18405&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/18405&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1668655857681&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;18405번: 경쟁적 전염&quot; data-og-description=&quot;첫째 줄에 자연수 N, K가 공백을 기준으로 구분되어 주어진다. (1 &amp;le; N &amp;le; 200, 1 &amp;le; K &amp;le; 1,000) 둘째 줄부터 N개의 줄에 걸쳐서 시험관의 정보가 주어진다. 각 행은 N개의 원소로 구성되며, 해당 위치&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/18405&quot; data-og-url=&quot;https://www.acmicpc.net/problem/18405&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cnhdC0/hyQBbDABHy/FDV1MM2rMuuJrYxfEQlzdk/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480,https://scrap.kakaocdn.net/dn/cx4VlM/hyQA7gQKAE/UbowiJh2ugjyunJAmeuhqK/img.png?width=525&amp;amp;height=311&amp;amp;face=0_0_525_311,https://scrap.kakaocdn.net/dn/9fdD2/hyQB3KGksE/P4oyoimkQzBz9iKD0e5Q20/img.png?width=521&amp;amp;height=309&amp;amp;face=0_0_521_309&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/18405&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/18405&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cnhdC0/hyQBbDABHy/FDV1MM2rMuuJrYxfEQlzdk/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480,https://scrap.kakaocdn.net/dn/cx4VlM/hyQA7gQKAE/UbowiJh2ugjyunJAmeuhqK/img.png?width=525&amp;amp;height=311&amp;amp;face=0_0_525_311,https://scrap.kakaocdn.net/dn/9fdD2/hyQB3KGksE/P4oyoimkQzBz9iKD0e5Q20/img.png?width=521&amp;amp;height=309&amp;amp;face=0_0_521_309');&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;18405번: 경쟁적 전염&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫째 줄에 자연수 N, K가 공백을 기준으로 구분되어 주어진다. (1 &amp;le; N &amp;le; 200, 1 &amp;le; K &amp;le; 1,000) 둘째 줄부터 N개의 줄에 걸쳐서 시험관의 정보가 주어진다. 각 행은 N개의 원소로 구성되며, 해당 위치&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&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;span style=&quot;letter-spacing: 0px;&quot;&gt;시간을 증가 시킨 후 다음 바이러스를 큐에 넣었다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;다른 답안을 보니 virus를 소팅하고 deque를 이용해 정석적인 BFS 방식으로 풀 수 있었는데 좀 돌아서 간 것 같다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1668655842170&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from collections import deque
import heapq

n, k = map(int, input().split())
arr = [[0]*(n+1) for _ in range(n+1)]
q = []
for i in range(1, n+1):
    data = list(map(int, input().split()))
    for j in range(1, n+1):
        arr[i][j] = data[j-1]
        if data[j-1] != 0:
            # virus
            heapq.heappush(q, (data[j-1], i, j))

# viruses.sort()
s, a, b = map(int, input().split())
dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]

if s == 0:
    print(arr[a][b])
    exit(0)

time = 0
next_viruses = []
while len(q) &amp;gt; 0:
    t, x, y = heapq.heappop(q)
    for i in range(4):
        nx = x + dx[i]
        ny = y + dy[i]
        if nx &amp;lt;= 0 or ny &amp;lt;= 0 or nx &amp;gt; n or ny &amp;gt; n or arr[nx][ny] != 0:
            continue
        arr[nx][ny] = t
        next_viruses.append((t, nx, ny))

    if len(q) == 0:
        time += 1
        if time == s:
            print(arr[a][b])
            exit(0)
        for virus in next_viruses:
            heapq.heappush(q, virus)
        next_viruses = []

print(arr[a][b])
exit(0)&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/BOJ</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/279</guid>
      <comments>https://gom20.tistory.com/279#entry279comment</comments>
      <pubDate>Thu, 17 Nov 2022 12:34:42 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 18352] 특정 거리의 도시 찾기 (Python)</title>
      <link>https://gom20.tistory.com/278</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/18352&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/18352&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1668649654393&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;18352번: 특정 거리의 도시 찾기&quot; data-og-description=&quot;첫째 줄에 도시의 개수 N,&amp;nbsp;도로의 개수 M, 거리 정보 K, 출발 도시의 번호 X가 주어진다. (2 &amp;le;&amp;nbsp;N&amp;nbsp;&amp;le; 300,000, 1 &amp;le;&amp;nbsp;M&amp;nbsp;&amp;le; 1,000,000, 1 &amp;le;&amp;nbsp;K&amp;nbsp;&amp;le; 300,000, 1 &amp;le;&amp;nbsp;X&amp;nbsp;&amp;le;&amp;nbsp;N) 둘째 줄부터 M개의 줄에 걸쳐서 두 개&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/18352&quot; data-og-url=&quot;https://www.acmicpc.net/problem/18352&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cQvduT/hyQBPZL3G9/cShNTSytInE2cj0NmKfQeK/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480,https://scrap.kakaocdn.net/dn/bCLJn3/hyQBPMe8uJ/yBRiYshDpFMEO7eD82r0Y0/img.jpg?width=495&amp;amp;height=493&amp;amp;face=0_0_495_493&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/18352&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/18352&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cQvduT/hyQBPZL3G9/cShNTSytInE2cj0NmKfQeK/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480,https://scrap.kakaocdn.net/dn/bCLJn3/hyQBPMe8uJ/yBRiYshDpFMEO7eD82r0Y0/img.jpg?width=495&amp;amp;height=493&amp;amp;face=0_0_495_493');&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;18352번: 특정 거리의 도시 찾기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫째 줄에 도시의 개수 N,&amp;nbsp;도로의 개수 M, 거리 정보 K, 출발 도시의 번호 X가 주어진다. (2 &amp;le;&amp;nbsp;N&amp;nbsp;&amp;le; 300,000, 1 &amp;le;&amp;nbsp;M&amp;nbsp;&amp;le; 1,000,000, 1 &amp;le;&amp;nbsp;K&amp;nbsp;&amp;le; 300,000, 1 &amp;le;&amp;nbsp;X&amp;nbsp;&amp;le;&amp;nbsp;N) 둘째 줄부터 M개의 줄에 걸쳐서 두 개&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BFS로 최단 거리를 만족하는 노드를 저장한다.&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1668649665616&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from collections import deque
import sys
input = sys.stdin.readline

# n노드, m간선, k최단거리, x시작노드
n, m, k, x = map(int, input().rstrip().split())

graph = [[] for _ in range(n+1)]
# 간선 정보 입력 받기

for _ in range(m):
    a, b = map(int, input().split())
    graph[a].append(b)


def bfs(graph, start, k):
    result = []
    visited = [False] * (n + 1)
    que = deque()
    visited[start] = True
    que.append((start, 0))

    while que:
        now, dist = que.popleft()
        flag = True if dist == k-1 else False
        for adj in graph[now]:
            if visited[adj]:
                continue
            else:
                visited[adj] = True
                if flag:
                    result.append(adj)
                else:
                    que.append((adj, dist + 1))

    if len(result) == 0:
        print(-1)
    else:
        result.sort()
        for r in result:
            print(r)

bfs(graph, x, k)&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/BOJ</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/278</guid>
      <comments>https://gom20.tistory.com/278#entry278comment</comments>
      <pubDate>Thu, 17 Nov 2022 10:47:58 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 3190] 뱀 (Python)</title>
      <link>https://gom20.tistory.com/277</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/3190&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/3190&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1668580167298&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;3190번: 뱀&quot; data-og-description=&quot;&amp;nbsp;'Dummy' 라는 도스게임이 있다. 이 게임에는 뱀이 나와서 기어다니는데, 사과를 먹으면 뱀 길이가 늘어난다. 뱀이 이리저리 기어다니다가 벽 또는 자기자신의 몸과 부딪히면 게임이 끝난다. 게임&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/3190&quot; data-og-url=&quot;https://www.acmicpc.net/problem/3190&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dCt9lf/hyQBaxfaAf/Fin7ny8irppKtpnZkEsqm1/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/3190&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/3190&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dCt9lf/hyQBaxfaAf/Fin7ny8irppKtpnZkEsqm1/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;3190번: 뱀&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;'Dummy' 라는 도스게임이 있다. 이 게임에는 뱀이 나와서 기어다니는데, 사과를 먹으면 뱀 길이가 늘어난다. 뱀이 이리저리 기어다니다가 벽 또는 자기자신의 몸과 부딪히면 게임이 끝난다. 게임&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&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;사과가 없으면 뱀의 꼬리 좌표 정보를 큐에서 제거한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1668580206193&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from collections import deque

n = int(input())
k = int(input())
dummy_map = [[0]*(n+1) for _ in range(n+1)]

# 사과 셋팅
for _ in range(k):
    a, b = map(int, input().split())
    dummy_map[a][b] = 1

# 방향 전환 정보 저장
dir_que = deque()
d = int(input())
for _ in range(d):
    x, dir = input().split()
    dir_que.append((int(x), dir))

# 뱀의 궤적 큐 생성
dummy_map[1][1] = 2
snake_que = deque()
snake_que.append((1, 1))


# 다음 위치가 유효한지 체크
def isValid(a, b):
    if a &amp;gt; n or b &amp;gt; n or a == 0 or b == 0:
        return False
    if dummy_map[a][b] == 2:
        return False
    return True

# 뱀의 방향
N, E, S, W = 0, 1, 2, 3
move = [(-1, 0), (0, 1), (1, 0), (0, -1)]
cur_dir = E

x = 0
a, b = 1, 1
while x &amp;lt;= 10000:
    x += 1
    a = a + move[cur_dir][0]
    b = b + move[cur_dir][1]

    if isValid(a, b):
        # 사과가 있는지 체크
        if dummy_map[a][b] == 0:
            # 사과가 없으면? 꼬리 지우고 머리 위치 입력
            tail = snake_que.popleft()
            dummy_map[tail[0]][tail[1]] = 0
            snake_que.append((a, b))
            dummy_map[a][b] = 2
        else:
            # 사과가 있으면?
            snake_que.append((a, b))
            dummy_map[a][b] = 2

        # 방향 전환
        if dir_que and x == dir_que[0][0]:
            dir_info = dir_que.popleft()
            if dir_info[1] == 'L':
                cur_dir = cur_dir - 1 if cur_dir &amp;gt;= 1 else 3
            else:
                cur_dir = cur_dir + 1 if cur_dir &amp;lt;= 2 else 0
    else:
        # 벽이나 몸체를 만났을 경우
        print(x)
        break&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/BOJ</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/277</guid>
      <comments>https://gom20.tistory.com/277#entry277comment</comments>
      <pubDate>Wed, 16 Nov 2022 15:31:08 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 자물쇠와 열쇠 (Python)</title>
      <link>https://gom20.tistory.com/276</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/60059&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/60059&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1668569834954&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;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/60059&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/g8q2z/hyQA3EHfg5/eUqqxT72vuxAOB7VQwLbqk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/cESeJ3/hyQA7G5ouA/JkdPWqxE3aFMD2oIHIIFQ0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/60059&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/60059&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/g8q2z/hyQA3EHfg5/eUqqxT72vuxAOB7VQwLbqk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/cESeJ3/hyQA7G5ouA/JkdPWqxE3aFMD2oIHIIFQ0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;programmers.co.kr&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1668569821842&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import copy

def lotate(key):
#     000    010     110
#     100 -&amp;gt; 100  -&amp;gt; 001
#     011    100     000
    
#     1행 -&amp;gt; 3열
#     2행 -&amp;gt; 2열
#     3행 -&amp;gt; 1열
    newkey = [[0 for _ in range(len(key))] for _ in range(len(key))]
    for row in range(len(key)):
        for col in range(len(key)):
            newkey[col][len(key)-1-row] = key[row][col]  
    return newkey


def isOpen(key, biglock):
    for i in range(0, len(biglock)-len(biglock)//3):
        for j in range(0, len(biglock)-len(biglock)//3):
            if checkRange(key, biglock, i, j):
                return True
    return False

def checkRange(key, biglock, row, col):
    biglockcopy = copy.deepcopy(biglock)
    for i in range(len(key)):
        for j in range(len(key)):
            biglockcopy[i+row][j+col] += key[i][j]
    
    for i in range(len(biglock)//3, len(biglock)-len(biglock)//3):
        for j in range(len(biglock)//3, len(biglock)-len(biglock)//3):
            if biglockcopy[i][j] != 1:
                return False

    return True
    
def solution(key, lock):
    answer = False
    n = len(lock)
    m = len(key)
    
    req_count = 0    
    biglock = [[0 for _ in range(n*3)] for _ in range(n*3)]
    for i in range(n, n*2):
        for j in range(n, n*2):
            biglock[i][j] = lock[i-n][j-n]
   
    for _ in range(4):
        if i != 0:
            key = lotate(key)  
        if isOpen(key, biglock):
            return True
            
    return answer&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/Programmers</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/276</guid>
      <comments>https://gom20.tistory.com/276#entry276comment</comments>
      <pubDate>Wed, 16 Nov 2022 12:40:09 +0900</pubDate>
    </item>
    <item>
      <title>[클라우드 네이티브] 클라우드 네이티브 기술이란?</title>
      <link>https://gom20.tistory.com/245</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;클라우드 네이티브의 정의&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1429&quot; data-origin-height=&quot;721&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k3PsY/btryDbuTlcA/V4yuFkjew1wkK4sTwYGOPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k3PsY/btryDbuTlcA/V4yuFkjew1wkK4sTwYGOPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k3PsY/btryDbuTlcA/V4yuFkjew1wkK4sTwYGOPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk3PsY%2FbtryDbuTlcA%2FV4yuFkjew1wkK4sTwYGOPk%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;1429&quot; height=&quot;721&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1429&quot; data-origin-height=&quot;721&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라우드 네이티브를 설명하기에 앞서 과거의 어플리케이션 구축 방식을 살펴 보면, 차근차근 단계를 밟아나가는 워터폴 방식과 하나의 덩어리로 이루어지는 모노리식 구조와 온프레미스 방식으로 시스템을 구축해 왔다.&lt;br /&gt;&lt;br /&gt;그러나 클라우드 시대가 도래함에 따라, 많은 시스템의 인프라가 클라우드를 전환이 되었다다. 이 때 주로 사용한 마이그레이션 방법이 리프트 앤 쉬프트 방식이다. 말 그대로, OS, 데이터, 애플리케이션을 그대로 클라우드로 옮기는 것을 의미한다. 이 방식은 어플리케이션 관점에서는 큰 변화가 없기 때문에, 클라우드가 제공하는 리소스 활용의 유연성과 확장성의 이점을 활용하는데는 한계가 있다.&lt;br /&gt;&lt;br /&gt;그래서 나온 개념이 바로 클라우드 네이티브이다. 클라우드 네이티브란 클라우드가 제공하는 장점을 최대한 활용할 수 있도록 시스템을 구축하는 접근방식과 기술을 의미한다. 네이티브라는 단어처럼 어플리케이션 설계 단계부터 클라우드 고려한 개발 방법론과 아키텍쳐를 제안하며, 클라우드 환경에서의 지속적인 개발과 자동화된 관리 환경을 제공할 수 있는 여러 가지 기술들을 제시한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;클라우드 네이티브 기술 핵심 요소 4가지&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1429&quot; data-origin-height=&quot;722&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dqiyhH/btryFonfx6x/po5OlSJZwMrK78vzodq1rK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dqiyhH/btryFonfx6x/po5OlSJZwMrK78vzodq1rK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dqiyhH/btryFonfx6x/po5OlSJZwMrK78vzodq1rK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdqiyhH%2FbtryFonfx6x%2Fpo5OlSJZwMrK78vzodq1rK%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;1429&quot; height=&quot;722&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1429&quot; data-origin-height=&quot;722&quot;/&gt;&lt;/span&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;클라우드 네이티브 기술의 핵심 요소에는 크게 4가지가 있다.&lt;br /&gt;&lt;br /&gt;첫 번째, DevOps&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DevOps란 개발과 운영의 합성어로 두 역할 간의 협업을 바탕으로 소프트웨어를 빠르게 고품질로 개발 운영하기 위한 문화, 방식, 도구의 조합을 의미한다.&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;두 번째, CI/CD&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DevOps를 실천하는 여러 도구들이 있는데 그 중에서도 DevOps의 핵심 요소인 자동화를 실현하는 기술이 바로 CI/CD 이다. CI/CD의 기본 개념은 지속적인 통합, 배포를 의미하는 것으로 애플리케이션 라이프 사이클 전체에 걸쳐 지속적인 자동화와 시각화, 프로세스 단순화가 핵심이다.&lt;br /&gt;&lt;br /&gt;세 번째, MSA&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마이크로 서비스 아키텍쳐는 업무 단위를 각각 독립적인 서비스로 구축하는 구조를 의미한다. 기존의 하나의 덩어리로 서비스간 결합도가 높은 모놀리식 시스템과는 달리 각각의 마이크로 서비스가 독립적으로 구축이 되고 배포되는 구조로 이루어져 있다. 따라서 고객의 요구와 기술적인 환경 변화에 빠르게 대응 가능하며 유연하게 시스템을 개발/운영할 수 있다.&lt;br /&gt;&lt;br /&gt;네 번째, 컨테이너&lt;br /&gt;MSA 애플리케이션은 수십에서 수백 개의 서비스로 이루어질 수 있고, 이렇게 만들어진 각각의 서비스는 컨테이너 기술을 통해 배포될 수 있다. 컨테이너란 인프라의 일관성을 유지하며 안전한 배포와 운영을 가능하게 해주는 기술로, 애플리케이션 실행에 필요한 라이브러리, 바이너리, 구성파일을 하나의 객체로 패키징하는 표준화된 방식을 제공한다. 따라서 어떤 인프라 환경에서든 동일하게 애플리케이션 실행이 보장된다. 높은 이식성과 경량화 특징을 가지고 있기 때문에, 클라우드 환경에서 MSA의 작은 서비스 단위를 실행하는데 있어서 많은 이점을 가진다.&lt;/p&gt;</description>
      <category> IT</category>
      <category>Cloud Native</category>
      <category>클라우드네이티브</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/245</guid>
      <comments>https://gom20.tistory.com/245#entry245comment</comments>
      <pubDate>Thu, 7 Apr 2022 13:23:28 +0900</pubDate>
    </item>
    <item>
      <title>[jqxGrid] cellsrenderer not working (callback function not called)</title>
      <link>https://gom20.tistory.com/236</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;jqxGrid cell을 커스텀하게 render할 필요가 있어서, column property에 cellsrenderer를 추가하여 콜백 함수를 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 별짓 다 해봐도 cellsrenderer로 설정한 콜백함수가 호출되지 않음&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;해결&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cellsformat, cellclassname, cellalign 등등 property를 하나씩 빼보면서 테스트 해봄.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 type='number' 제거하니 호출되는 것 확인.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;When you want to use &quot;cellsrenderer&quot; property, don't use &quot;type&quot; property at the same time.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category> IT</category>
      <category>cellsrenderer</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/236</guid>
      <comments>https://gom20.tistory.com/236#entry236comment</comments>
      <pubDate>Thu, 27 Jan 2022 17:34:06 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 신고 결과 받기 (Java)</title>
      <link>https://gom20.tistory.com/235</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/92334?language=java&quot;&gt;https://programmers.co.kr/learn/courses/30/lessons/92334?language=java&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1642682287177&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;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/92334?language=java&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/92334?language=java&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/k7GiK/hyM9vrwnl7/mK0O1JHBDdLfEFuoSdJvQ1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/dK3TL6/hyM9gHTjGI/wK68jEEZRxfKUiPZO3TkGK/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/92334?language=java&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/92334?language=java&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/k7GiK/hyM9vrwnl7/mK0O1JHBDdLfEFuoSdJvQ1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/dK3TL6/hyM9gHTjGI/wK68jEEZRxfKUiPZO3TkGK/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626');&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;programmers.co.kr&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Level1 쉬운 문제이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HashMap 사용하여 쉽게 풀 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1642682295277&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.*;
class Solution {
    public int[] solution(String[] id_list, String[] report, int k) {
        int[] answer = new int[id_list.length];
        
        HashMap&amp;lt;String, ArrayList&amp;lt;String&amp;gt;&amp;gt; reportingUsers = new HashMap&amp;lt;String, ArrayList&amp;lt;String&amp;gt;&amp;gt;();
        HashMap&amp;lt;String, Integer&amp;gt; reportedCnt = new HashMap&amp;lt;String, Integer&amp;gt;();
        HashMap&amp;lt;String, Integer&amp;gt; mailCnt = new HashMap&amp;lt;String, Integer&amp;gt;();
        for(String name : id_list){
            reportingUsers.put(name, new ArrayList&amp;lt;String&amp;gt;());
            reportedCnt.put(name, 0);
            mailCnt.put(name, 0);
        }
        for(int i = 0; i &amp;lt; report.length; i++){
            String[] arr = report[i].split(&quot; &quot;);
            String reportingUser = arr[0];
            String reportedUser = arr[1];
            
            if(reportingUsers.get(reportedUser).contains(reportingUser)) continue;
            reportingUsers.get(reportedUser).add(reportingUser);
            reportedCnt.put(reportedUser, reportedCnt.get(reportedUser) + 1);
        }
        
        for(String name : id_list){
            if(reportedCnt.get(name) &amp;gt;= k){
                for(String reportingUser : reportingUsers.get(name)){
                    mailCnt.put(reportingUser, mailCnt.get(reportingUser) + 1);
                }
            }
        }
        
        for(int i = 0; i &amp;lt; id_list.length; i++){
            answer[i] = mailCnt.get(id_list[i]);
        }
        return answer;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/Programmers</category>
      <category>HashMap</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/235</guid>
      <comments>https://gom20.tistory.com/235#entry235comment</comments>
      <pubDate>Thu, 20 Jan 2022 21:39:57 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 1167] 트리의 지름 (Java)</title>
      <link>https://gom20.tistory.com/234</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1167&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/1167&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1641117256018&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;1167번: 트리의 지름&quot; data-og-description=&quot;트리가 입력으로 주어진다. 먼저 첫 번째 줄에서는 트리의 정점의 개수 V가 주어지고 (2 &amp;le; V &amp;le; 100,000)둘째 줄부터 V개의 줄에 걸쳐 간선의 정보가 다음과 같이 주어진다. 정점 번호는 1부터 V까지&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/1167&quot; data-og-url=&quot;https://www.acmicpc.net/problem/1167&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bUOhIU/hyMWh0JGMU/8YOkz0sCc5Ws6HxgxwEGbk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1167&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/1167&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bUOhIU/hyMWh0JGMU/8YOkz0sCc5Ws6HxgxwEGbk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;1167번: 트리의 지름&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;트리가 입력으로 주어진다. 먼저 첫 번째 줄에서는 트리의 정점의 개수 V가 주어지고 (2 &amp;le; V &amp;le; 100,000)둘째 줄부터 V개의 줄에 걸쳐 간선의 정보가 다음과 같이 주어진다. 정점 번호는 1부터 V까지&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&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;span style=&quot;color: #ee2323;&quot;&gt; 가장 먼 노드&lt;/span&gt;를 구한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;해당 노드&lt;/span&gt;에서 DFS 알고리즘을 수행하여 가장 먼 거리를 구하면 그 값이 트리의 지름이 된다.&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;a href=&quot;https://blog.myungwoo.kr/112&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://blog.myungwoo.kr/112&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1641117344704&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;트리의 지름 구하기&quot; data-og-description=&quot;트리에서 지름이란, 가장 먼 두 정점 사이의 거리 혹은 가장 먼 두 정점을 연결하는 경로를 의미한다. 선형 시간안에 트리에서 지름을 구하는 방법은 다음과 같다: 1. 트리에서 임의의&amp;nbsp;정점 $x$를&quot; data-og-host=&quot;blog.myungwoo.kr&quot; data-og-source-url=&quot;https://blog.myungwoo.kr/112&quot; data-og-url=&quot;https://blog.myungwoo.kr/112&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/clqiy3/hyMWvYXPMz/VnzNJ92m4sA3enzjuqCma0/img.png?width=744&amp;amp;height=285&amp;amp;face=0_0_744_285,https://scrap.kakaocdn.net/dn/ba92M0/hyMWjqHaiq/WjQYGZhi7BJmW0pTYwGI7k/img.png?width=744&amp;amp;height=285&amp;amp;face=0_0_744_285&quot;&gt;&lt;a href=&quot;https://blog.myungwoo.kr/112&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://blog.myungwoo.kr/112&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/clqiy3/hyMWvYXPMz/VnzNJ92m4sA3enzjuqCma0/img.png?width=744&amp;amp;height=285&amp;amp;face=0_0_744_285,https://scrap.kakaocdn.net/dn/ba92M0/hyMWjqHaiq/WjQYGZhi7BJmW0pTYwGI7k/img.png?width=744&amp;amp;height=285&amp;amp;face=0_0_744_285');&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;트리에서 지름이란, 가장 먼 두 정점 사이의 거리 혹은 가장 먼 두 정점을 연결하는 경로를 의미한다. 선형 시간안에 트리에서 지름을 구하는 방법은 다음과 같다: 1. 트리에서 임의의&amp;nbsp;정점 $x$를&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blog.myungwoo.kr&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;package tree;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class BOJ1167 {

    static int V;
    static class Edge{
        int to;
        int weight;
        public Edge(int to, int weight){
            this.to = to;
            this.weight = weight;
        }
    }
    static ArrayList&amp;lt;Edge&amp;gt;[] adjs = null;

    static boolean[] visited;
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        V = Integer.parseInt(br.readLine());
        adjs = new ArrayList[V+1];
        for(int i = 1; i &amp;lt;= V; i++){
            adjs[i] = new ArrayList&amp;lt;Edge&amp;gt;();
        }

        StringTokenizer st = null;
        for(int i = 1; i &amp;lt;= V; i++){
            st = new StringTokenizer(br.readLine());
            int from = Integer.parseInt(st.nextToken());
            while(true){
                int to = Integer.parseInt(st.nextToken());
                if(to == -1) break;
                int weight = Integer.parseInt(st.nextToken());
                adjs[from].add(new Edge(to, weight));
            }
        }

        // 임의 정점에서 가장 먼 노드 구하기
        visited = new boolean[V+1];
        visited[1] = true;
        dfs(1, 0);

        // 위에서 구한 노드에서 가장 먼 거리 구하기
        max = 0;
        visited = new boolean[V+1];
        visited[target] = true;
        dfs(target, 0);

        System.out.println(max);
    }
    static int max, target;
    public static void dfs(int v, int weight){
        if(max &amp;lt; weight){
            max = weight;
            target = v;
        }
        for(Edge e : adjs[v]){
            if(visited[e.to]) continue;
            visited[e.to] = true;
            dfs(e.to, e.weight + weight);
        }
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/BOJ</category>
      <category>DFS</category>
      <category>Tree</category>
      <category>트리의지름</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/234</guid>
      <comments>https://gom20.tistory.com/234#entry234comment</comments>
      <pubDate>Sun, 2 Jan 2022 18:58:53 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 10159] 저울 (Java)</title>
      <link>https://gom20.tistory.com/233</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/10159&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/10159&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1641027007381&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;10159번: 저울&quot; data-og-description=&quot;첫 줄에는 물건의 개수 N 이 주어지고, 둘째 줄에는 미리 측정된 물건 쌍의 개수 M이 주어진다. 단, 5 &amp;le; N &amp;le; 100 이고, 0 &amp;le; M &amp;le; 2,000이다. 다음 M개의 줄에 미리 측정된 비교 결과가 한 줄에 하나씩 &quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/10159&quot; data-og-url=&quot;https://www.acmicpc.net/problem/10159&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bZO0Wj/hyMUX26abS/KZ6o2IdEoeL3Vdt9KQaCi0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/10159&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/10159&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bZO0Wj/hyMUX26abS/KZ6o2IdEoeL3Vdt9KQaCi0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;10159번: 저울&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫 줄에는 물건의 개수 N 이 주어지고, 둘째 줄에는 미리 측정된 물건 쌍의 개수 M이 주어진다. 단, 5 &amp;le; N &amp;le; 100 이고, 0 &amp;le; M &amp;le; 2,000이다. 다음 M개의 줄에 미리 측정된 비교 결과가 한 줄에 하나씩&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플로이드 와샬 알고리즘을 사용하여 풀 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) 1 &amp;gt; 2 , 2 &amp;gt; 3&amp;nbsp; &amp;nbsp;===&amp;gt;&amp;nbsp; 1 &amp;gt; 3&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1641027027898&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package floyd;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;

public class BOJ10159 {
	
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	
		int N = Integer.parseInt(br.readLine());
		int M = Integer.parseInt(br.readLine());
		
		int map[][] = new int[N+1][N+1];
		
		StringTokenizer st = null;
		for(int i = 1; i &amp;lt;= M; i++) {
			st = new StringTokenizer(br.readLine());
			int a = Integer.parseInt(st.nextToken());
			int b = Integer.parseInt(st.nextToken());
			// a &amp;gt; b
			map[a][b] = 1;
			map[b][a] = -1;
		}
		
		for(int k = 1; k &amp;lt;= N; k++) {
			for(int i = 1; i &amp;lt;= N; i++) {
				for(int j = 1; j &amp;lt;= N; j++) {
					if(map[i][k] == 1 &amp;amp;&amp;amp; map[k][j] == 1) {
						map[i][j] = 1;
						map[j][i] = -1;
					}
					if(map[i][k] == -1 &amp;amp;&amp;amp; map[k][j] == -1) {
						map[i][j] = -1;
						map[j][i] = 1;
					}
				}
			}
		}
		
		for(int i = 1; i &amp;lt;= N; i++) {
			int cnt = 0;
			for(int j = 1; j &amp;lt;= N; j++) {
				if(i == j) continue;
				if(map[i][j] == 0) cnt++;
			}
			System.out.println(cnt);
		}	
	}
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/BOJ</category>
      <category>플로이드와샬</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/233</guid>
      <comments>https://gom20.tistory.com/233#entry233comment</comments>
      <pubDate>Sat, 1 Jan 2022 17:51:03 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 11779] 최소비용 구하기 2 (Java)</title>
      <link>https://gom20.tistory.com/232</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/11779&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/11779&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1640845971876&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;11779번: 최소비용 구하기 2&quot; data-og-description=&quot;첫째 줄에 도시의 개수 n(1&amp;le;n&amp;le;1,000)이 주어지고 둘째 줄에는 버스의 개수 m(1&amp;le;m&amp;le;100,000)이 주어진다. 그리고 셋째 줄부터 m+2줄까지 다음과 같은 버스의 정보가 주어진다. 먼저 처음에는 그 버스&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/11779&quot; data-og-url=&quot;https://www.acmicpc.net/problem/11779&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/fWUMs/hyMTMtcZnM/blcTjkIyzGc8Fd73h0je2k/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/11779&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/11779&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/fWUMs/hyMTMtcZnM/blcTjkIyzGc8Fd73h0je2k/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;11779번: 최소비용 구하기 2&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫째 줄에 도시의 개수 n(1&amp;le;n&amp;le;1,000)이 주어지고 둘째 줄에는 버스의 개수 m(1&amp;le;m&amp;le;100,000)이 주어진다. 그리고 셋째 줄부터 m+2줄까지 다음과 같은 버스의 정보가 주어진다. 먼저 처음에는 그 버스&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&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;u&gt;&lt;b&gt;최소 비용으로 가는 경로&lt;/b&gt; &lt;/u&gt;또한 출력해야 한다는 점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cost 배열을 2차 배열로 만들어서 &lt;span style=&quot;color: #ee2323;&quot;&gt;최소 비용과 함께 갱신할 때의 이전 노드값을 같이 저장&lt;/span&gt;하였다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다익스트라 알고리즘 수행 후, 도착지 노드부터 이전 노드 값을 거꾸로 탐색하여 시작 노드까지의 경로를 구하였다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;package dijkstra;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.*;

public class BOJ11779 {
    static class Edge {
        int to;
        int cost;
        Edge(int to, int cost){
            this.to = to;
            this.cost = cost;
        }
    }

    static int N, M, S, E;
    static ArrayList&amp;lt;Edge&amp;gt;[] adjs;
    static int[][] cost;
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        N = Integer.parseInt(br.readLine());
        M = Integer.parseInt(br.readLine());

        adjs = new ArrayList[N+1];
        for(int i = 1; i &amp;lt;= N; i++){
            adjs[i] = new ArrayList&amp;lt;Edge&amp;gt;();
        }
        cost = new int[N+1][2];
        for(int i = 1; i &amp;lt;= N; i++){
            cost[i][0] = Integer.MAX_VALUE;
        }

        StringTokenizer st = null;
        for(int i = 0; i &amp;lt; M; i++){
            st = new StringTokenizer(br.readLine());
            int from = Integer.parseInt(st.nextToken());
            int to = Integer.parseInt(st.nextToken());
            int cost = Integer.parseInt(st.nextToken());
            adjs[from].add(new Edge(to, cost));
        }

        st = new StringTokenizer(br.readLine());
        S = Integer.parseInt(st.nextToken());
        E = Integer.parseInt(st.nextToken());

        dijkstra();


        Stack&amp;lt;Integer&amp;gt; path = new Stack&amp;lt;&amp;gt;();
        path.push(E);
        while(true){
            int prev = cost[path.peek()][1];
            path.push(prev);
            if(prev == S) break;
        }

        bw.write(cost[E][0] + &quot;\n&quot;);
        bw.write(path.size()+ &quot;\n&quot;);
        StringBuilder sb = new StringBuilder();
        while(!path.isEmpty()){
            sb.append(path.pop() + &quot; &quot;);
        }
        bw.write(sb.toString());
        bw.flush();
    }
    static class Info {
        int node;
        int accuCost;
        public Info(int node, int accuCost){
            this.node = node;
            this.accuCost = accuCost;
        }
    }
    public static void dijkstra(){
        cost[S][0] = 0;
        cost[S][1] = S;
        PriorityQueue&amp;lt;Info&amp;gt; pq = new PriorityQueue&amp;lt;Info&amp;gt;(
                new Comparator&amp;lt;Info&amp;gt;() {
                    @Override
                    public int compare(Info o1, Info o2) {
                        return o1.accuCost - o2.accuCost;
                    }
                }
        );
        pq.offer(new Info(S, 0));

        while(!pq.isEmpty()){
            Info info = pq.poll();
            if(info.accuCost &amp;gt; cost[info.node][0]) continue;
            for(Edge edge : adjs[info.node]){
                if(cost[edge.to][0] &amp;lt;= info.accuCost + edge.cost) continue;
                cost[edge.to][0] = info.accuCost + edge.cost;
                cost[edge.to][1] = info.node;
                pq.offer(new Info(edge.to, cost[edge.to][0]));
            }
        }
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/BOJ</category>
      <category>dijkstra</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/232</guid>
      <comments>https://gom20.tistory.com/232#entry232comment</comments>
      <pubDate>Thu, 30 Dec 2021 15:36:52 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 6603] 로또 (Java)</title>
      <link>https://gom20.tistory.com/231</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/6603&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/6603&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1640673826341&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;6603번: 로또&quot; data-og-description=&quot;입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스는 한 줄로 이루어져 있다. 첫 번째 수는 k (6 &amp;lt; k &amp;lt; 13)이고, 다음 k개 수는 집합 S에 포함되는 수이다. S의 원소는 오름차순으로 &quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/6603&quot; data-og-url=&quot;https://www.acmicpc.net/problem/6603&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/e6czI/hyMRDjE35S/kjk09SDQrQnkAFOaRYhh81/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/6603&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/6603&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/e6czI/hyMRDjE35S/kjk09SDQrQnkAFOaRYhh81/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;6603번: 로또&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스는 한 줄로 이루어져 있다. 첫 번째 수는 k (6 &amp;lt; k &amp;lt; 13)이고, 다음 k개 수는 집합 S에 포함되는 수이다. S의 원소는 오름차순으로&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;완전탐색 문제로 재귀 함수를 사용하여 가능한 조합을 구한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;k개 수에서&amp;nbsp;순서 상관 없이, 중복 없이 6개의 수를 뽑는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;package bruteforce;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class BOJ6603 {

    static int k;
    static int[] arr, result;
    static boolean[] used;
    static BufferedWriter bw;
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        bw = new BufferedWriter(new OutputStreamWriter(System.out));
        while(true){
            StringTokenizer st = new StringTokenizer(br.readLine());
            k = Integer.parseInt(st.nextToken());
            if(k == 0) break;

            arr = new int[k];
            result = new int[6];
            used = new boolean[k];
            for(int i = 0; i &amp;lt; k ; i++){
                arr[i] = Integer.parseInt(st.nextToken());
            }

            recur(0, 0, result);
            bw.flush();
            bw.write(&quot;\n&quot;);
        }
    }

    public static void recur(int idx, int cnt, int[] result) throws Exception {
        if(cnt == 6){
            Arrays.sort(result);
            StringBuilder sb = new StringBuilder();
            for(int num : result){
                sb.append(num + &quot; &quot;);
            }
            bw.write(sb.toString());
            bw.write(&quot;\n&quot;);
            return;
        }

        for(int i = idx; i &amp;lt; k; i++){
            if(used[i]) continue;
            used[i] = true;
            result[cnt] = arr[i];
            recur(i+1, cnt+1, result);
            used[i] = false;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/BOJ</category>
      <category>bruteforce</category>
      <category>Combination</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/231</guid>
      <comments>https://gom20.tistory.com/231#entry231comment</comments>
      <pubDate>Tue, 28 Dec 2021 15:45:30 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 1261] 알고스팟 (Java)</title>
      <link>https://gom20.tistory.com/230</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1261&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/1261&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1640583465645&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;1261번: 알고스팟&quot; data-og-description=&quot;첫째 줄에 미로의 크기를 나타내는 가로 크기 M, 세로 크기 N (1 &amp;le; N, M &amp;le; 100)이 주어진다. 다음 N개의 줄에는 미로의 상태를 나타내는 숫자 0과 1이 주어진다. 0은 빈 방을 의미하고, 1은&amp;nbsp;벽을 의미&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/1261&quot; data-og-url=&quot;https://www.acmicpc.net/problem/1261&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/zdTL8/hyMRHLTSeP/sE9ckrrumbf12Z9baMkSlk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1261&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/1261&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/zdTL8/hyMRHLTSeP/sE9ckrrumbf12Z9baMkSlk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;1261번: 알고스팟&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫째 줄에 미로의 크기를 나타내는 가로 크기 M, 세로 크기 N (1 &amp;le; N, M &amp;le; 100)이 주어진다. 다음 N개의 줄에는 미로의 상태를 나타내는 숫자 0과 1이 주어진다. 0은 빈 방을 의미하고, 1은&amp;nbsp;벽을 의미&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1640583451184&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package dijkstra;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

public class BOJ1261 {

    static int M, N;
    static int[][] map;
    static int[][] counts;

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());

        counts = new int[M +1][N +1];
        for(int i = 1; i &amp;lt;= M; i++){
            for(int j = 1; j &amp;lt;= N; j++){
                counts[i][j] = Integer.MAX_VALUE;
            }
        }
        map = new int[M +1][N +1];
        for(int i = 1; i &amp;lt;= M; i++){
            char[] arr = br.readLine().toCharArray();
            for(int j = 1; j &amp;lt;= N; j++){
                map[i][j] = Integer.parseInt(String.valueOf(arr[j-1]));
            }
        }
        dijkstra();

        System.out.println(counts[M][N]);
    }

    static int[][] dir = new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

    static class Info implements Comparable&amp;lt;Info&amp;gt; {
        int x;
        int y;
        int accCnt;

        public Info(int x, int y, int count){
            this.x = x;
            this.y = y;
            this.accCnt = count;
        }

        @Override
        public int compareTo(Info o) {
            return this.accCnt - o.accCnt;
        }
    }
    public static void dijkstra(){
        PriorityQueue&amp;lt;Info&amp;gt; pq = new PriorityQueue&amp;lt;Info&amp;gt;();
        counts[1][1] = 0;
        pq.offer(new Info(1, 1, 0));

        while(!pq.isEmpty()){
            Info info = pq.poll();
            int x = info.x;
            int y = info.y;
            int accuCnt = info.accCnt;

            if(counts[x][y] &amp;lt; accuCnt) continue;

            for(int[] d : dir ){
                int nx = x + d[0];
                int ny = y + d[1];
                if(!isValid(nx, ny)) continue;

                int nCnt = accuCnt + (map[nx][ny] == 1 ? 1 : 0);
                if(nCnt &amp;lt; counts[nx][ny]) {
                    counts[nx][ny] = nCnt;
                    pq.offer(new Info(nx, ny, nCnt));
                }
            }
        }
    }

    public static boolean isValid(int nx, int ny){
        if(nx &amp;lt; 1|| ny &amp;lt; 1 || nx &amp;gt; M || ny &amp;gt; N) return false;
        return true;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/BOJ</category>
      <category>dijkstra</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/230</guid>
      <comments>https://gom20.tistory.com/230#entry230comment</comments>
      <pubDate>Mon, 27 Dec 2021 14:40:17 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 2583] 영역 구하기 (Java)</title>
      <link>https://gom20.tistory.com/229</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2583&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/2583&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1640427596620&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;2583번: 영역 구하기&quot; data-og-description=&quot;첫째 줄에 M과 N, 그리고 K가 빈칸을 사이에 두고 차례로 주어진다. M, N, K는 모두 100 이하의 자연수이다. 둘째 줄부터 K개의 줄에는 한 줄에 하나씩 직사각형의 왼쪽 아래 꼭짓점의 x, y좌표값과 오&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/2583&quot; data-og-url=&quot;https://www.acmicpc.net/problem/2583&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bAyFbs/hyMQsgKVPD/dnYEBvrWm26WeFx1T9Nw8k/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2583&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/2583&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bAyFbs/hyMQsgKVPD/dnYEBvrWm26WeFx1T9Nw8k/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;2583번: 영역 구하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫째 줄에 M과 N, 그리고 K가 빈칸을 사이에 두고 차례로 주어진다. M, N, K는 모두 100 이하의 자연수이다. 둘째 줄부터 K개의 줄에는 한 줄에 하나씩 직사각형의 왼쪽 아래 꼭짓점의 x, y좌표값과 오&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좌표 영역을 칠하고, DFS로 빈 공간의 개수와 넓이를 구한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;영역 칸의 개수를 구해야 하기 때문에&lt;/u&gt;, 입력된 좌표를 그대로 사용하면 정확한 답을 구할 수 없다.-&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 해결하기 위해, 칠할 영역 &lt;u&gt;시작 좌표의 x, y 좌표는 +1을 해주어서 좌표의 기준을 우측 대각선 위로&lt;/u&gt; 동일하게 맞춰주었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;307&quot; data-origin-height=&quot;284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/szNIn/btroStyiZSa/uNokPNxhhHldNhDYsOGWK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/szNIn/btroStyiZSa/uNokPNxhhHldNhDYsOGWK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/szNIn/btroStyiZSa/uNokPNxhhHldNhDYsOGWK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FszNIn%2FbtroStyiZSa%2FuNokPNxhhHldNhDYsOGWK0%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;307&quot; height=&quot;284&quot; data-origin-width=&quot;307&quot; data-origin-height=&quot;284&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) 칠해야 할 영역의 시작 좌표가 0, 0 일 경우 1, 1로 변경해서 칠한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1640427588734&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package dfs;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.StringTokenizer;

public class BOJ2583 {
    static int M, N, K, size;
    static int[][] map;
    static int[][] dir = new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        M = Integer.parseInt(st.nextToken());
        N = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());

        map = new int[N+1][M+1];
        for(int i = 0; i &amp;lt; K; i++){
            st = new StringTokenizer(br.readLine());
            int sx = Integer.parseInt(st.nextToken()) + 1;
            int sy = Integer.parseInt(st.nextToken()) + 1;
            int ex = Integer.parseInt(st.nextToken());
            int ey = Integer.parseInt(st.nextToken());

            for(int x = sx; x &amp;lt;= ex; x++){
                for(int y = sy; y &amp;lt;= ey; y++){
                    map[x][y] = 1;
                }
            }
        }

        ArrayList&amp;lt;Integer&amp;gt; answer = new ArrayList&amp;lt;Integer&amp;gt;();
        for(int i = 1; i &amp;lt;= N; i++){
            for(int j = 1; j &amp;lt;= M; j++){
                if(map[i][j] == 0){
                    size = 0;
                    dfs(i, j);
                    answer.add(size);
                }
            }
        }
        System.out.println(answer.size());
        Collections.sort(answer);
        StringBuilder sb = new StringBuilder();
        for(int n : answer){
            sb.append(n + &quot; &quot;);
        }
        System.out.println(sb.toString());
    }

    public static void dfs(int x, int y){
//        System.out.println(x+&quot;, &quot;+y);
        map[x][y] = 1;
        size++;
        for(int[] d : dir){
            int nx = x + d[0];
            int ny = y + d[1];
            if(isValid(nx, ny)){
                dfs(nx, ny);
            }
        }
    }

    public static boolean isValid(int nx, int ny){
        if(nx &amp;lt; 1 || ny &amp;lt; 1 || nx &amp;gt; N || ny &amp;gt; M) return false;
        if(map[nx][ny] == 1) return false;
        return true;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/BOJ</category>
      <category>DFS</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/229</guid>
      <comments>https://gom20.tistory.com/229#entry229comment</comments>
      <pubDate>Sat, 25 Dec 2021 19:25:02 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 1074] Z (Java)</title>
      <link>https://gom20.tistory.com/228</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1074&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/1074&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1640317140106&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;1074번: Z&quot; data-og-description=&quot;한수는 크기가 2N &amp;times; 2N인 2차원 배열을 Z모양으로 탐색하려고 한다. 예를 들어, 2&amp;times;2배열을 왼쪽 위칸, 오른쪽 위칸, 왼쪽 아래칸, 오른쪽 아래칸 순서대로 방문하면 Z모양이다. N &amp;gt;&amp;nbsp;1인 경우, 배열을&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/1074&quot; data-og-url=&quot;https://www.acmicpc.net/problem/1074&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bwRfZb/hyMO2P3KX7/tu82FbhuJdxjcTuK9mmGj1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1074&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/1074&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bwRfZb/hyMO2P3KX7/tu82FbhuJdxjcTuK9mmGj1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;1074번: Z&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;한수는 크기가 2N &amp;times; 2N인 2차원 배열을 Z모양으로 탐색하려고 한다. 예를 들어, 2&amp;times;2배열을 왼쪽 위칸, 오른쪽 위칸, 왼쪽 아래칸, 오른쪽 아래칸 순서대로 방문하면 Z모양이다. N &amp;gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&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;유사 문제&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gom20.tistory.com/142&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2021.11.16 - [Problem Solving/BOJ] - [BOJ 2630] 색종이 만들기 (Java)&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gom20.tistory.com/163&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2021.11.23 - [Problem Solving/Programmers] - [프로그래머스] 쿼드 압축 후 개수 세기 (Java)&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gom20.tistory.com/143&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2021.11.17 - [Problem Solving/BOJ] - [BOJ 1992] 쿼드트리 (Java)&lt;/a&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;span style=&quot;color: #ee2323;&quot;&gt;전수로 분할정복을 할 경우 시간 초과&lt;/span&gt;가 발생한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주어진 범위를 가지고 &lt;u&gt;(R, C) 좌표가 어떤 사분면에 속해 있는지 판단&lt;/u&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;(사분면의 순서는 문제에 나와있는 순서로 정하여 풀었다. 수학적 지식X)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;package divideconquer;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class BOJ1074 {

    static int N, R, C, answer;
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        R = Integer.parseInt(st.nextToken());
        C = Integer.parseInt(st.nextToken());
        // 2^N * 2^N 행렬

        divide(0, 0, (int)Math.pow(2, N));
    }

    public static int[][] order = {{0, 0}, {0, 1}, {1, 0}, {1, 1}};
    public static void divide(int x, int y, int n){
        if(n &amp;gt; 2){
            int quarterSpace = getQuarterSpace(x, y, n);
            if(quarterSpace == 1){
                divide(x, y, n/2); // up left 1
            } else if(quarterSpace == 2){
                answer += Math.pow(n, 2)*((double)1/4);
                divide(x, y+n/2, n/2); // up right 2
            }else if(quarterSpace == 3){
                answer += Math.pow(n, 2)*((double)2/4);
                divide(x+n/2, y, n/2); // down left 3
            } else {
                answer += Math.pow(n, 2)*((double)3/4);
                divide(x+n/2, y+n/2, n/2); // down right 4
            }
        } else {
//            System.out.println(x + &quot;, &quot; + y);
            for(int[] o : order){
                int r = x + o[0];
                int c = y + o[1];
                if(r == R &amp;amp;&amp;amp; c == C){
                    System.out.println(answer);
                    System.exit(0);
                }
                answer++;
            }
        }
    }

    public static int getQuarterSpace(int x, int y, int n){
        int rs = 0;
        if(R &amp;gt;= x &amp;amp;&amp;amp; R &amp;lt; x+n/2 &amp;amp;&amp;amp; C &amp;gt;= y &amp;amp;&amp;amp; C &amp;lt; y+n/2) rs = 1;
        if(R &amp;gt;= x &amp;amp;&amp;amp; R &amp;lt; x+n/2 &amp;amp;&amp;amp; C &amp;gt;= y+n/2 &amp;amp;&amp;amp; C &amp;lt; y+n/2+n/2) rs = 2;
        if(R &amp;gt;= x+n/2 &amp;amp;&amp;amp; R &amp;lt; x+n/2+n/2 &amp;amp;&amp;amp; C &amp;gt;= y &amp;amp;&amp;amp; C &amp;lt; y+n/2) rs = 3;
        if(R &amp;gt;= x+n/2 &amp;amp;&amp;amp; R &amp;lt; x+n/2+n/2 &amp;amp;&amp;amp; C &amp;gt;= y+n/2 &amp;amp;&amp;amp; C &amp;lt; y+n/2+n/2) rs = 4;
        return rs;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/BOJ</category>
      <category>divideandconquer</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/228</guid>
      <comments>https://gom20.tistory.com/228#entry228comment</comments>
      <pubDate>Fri, 24 Dec 2021 12:44:24 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 16234] 인구 이동 (Java, Python)</title>
      <link>https://gom20.tistory.com/227</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/16234&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/16234&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1640252449796&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;16234번: 인구 이동&quot; data-og-description=&quot;N&amp;times;N크기의 땅이 있고, 땅은 1&amp;times;1개의 칸으로 나누어져 있다. 각각의 땅에는 나라가 하나씩 존재하며, r행 c열에 있는 나라에는 A[r][c]명이 살고 있다. 인접한 나라 사이에는 국경선이 존재한다. 모&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/16234&quot; data-og-url=&quot;https://www.acmicpc.net/problem/16234&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bt81xJ/hyMN75XosB/IZfVK0uiMjRQdm5218Chg1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/16234&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/16234&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bt81xJ/hyMN75XosB/IZfVK0uiMjRQdm5218Chg1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;16234번: 인구 이동&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;N&amp;times;N크기의 땅이 있고, 땅은 1&amp;times;1개의 칸으로 나누어져 있다. 각각의 땅에는 나라가 하나씩 존재하며, r행 c열에 있는 나라에는 A[r][c]명이 살고 있다. 인접한 나라 사이에는 국경선이 존재한다. 모&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연합을 모두 찾은 후에 인구이동이 되어야 하므로, 찾은 연합을 저장해 둘 자료 구조를 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 맵을 순회하면서 DFS로 연합을 찾아서 저장한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 연합을 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;u&gt;모두 찾은 후에,&lt;/u&gt;&lt;/span&gt; 연합 내 총 인구/나라 개수를 계산하여 각 나라의 인구를 갱신한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 두 과정을 반복 한다. 연합을 찾았는데 연합의 개수가 0개인 경우 Loop를 종료한다.&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;package simulation;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class BOJ16234 {

    static class Union{
        int total;
        int average;
        ArrayList&amp;lt;Country&amp;gt; countries;

        Union(ArrayList&amp;lt;Country&amp;gt; countries){
            this.countries = countries;
            for(Country country: countries){
                total += map[country.x][country.y];
            }
            average = total /countries.size();
        }

        void updatePeopleCount(){
            for(Country country : countries){
                map[country.x][country.y] = average;
            }
        }
    }

    static class Country{
        int x;
        int y;

        Country(int x, int y){
            this.x = x;
            this.y = y;
        }
    }

    static int N, L, R;
    static int[][] map;
    static boolean[][] visited;
    static int[][] dir = new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    static ArrayList&amp;lt;Union&amp;gt; unions = new ArrayList&amp;lt;Union&amp;gt;();
    public static void main(String[] args) throws Exception  {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        L = Integer.parseInt(st.nextToken());
        R = Integer.parseInt(st.nextToken());
        map = new int[N][N];
        for(int i = 0; i &amp;lt; N; i++){
            st = new StringTokenizer(br.readLine());
            for(int j = 0; j &amp;lt; N; j++){
                map[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        int day = 0;
        while(true){
            unions.clear();
            visited = new boolean[N][N];
            for(int i = 0; i &amp;lt; N; i++){
                for(int j = 0; j &amp;lt; N; j++){
                    if(visited[i][j]) continue;

                    visited[i][j] = true;
                    ArrayList&amp;lt;Country&amp;gt; countries = new ArrayList&amp;lt;Country&amp;gt;();
                    findUnion(i, j, countries);
                    if(countries.size() &amp;gt; 1){
                        unions.add(new Union(countries));
                    }
                }
            }
            for(Union union : unions){
                union.updatePeopleCount();
            }
            if(unions.size() == 0) break;
            day++;
        }

        System.out.println(day);

    }

    public static void findUnion(int x, int y, ArrayList&amp;lt;Country&amp;gt; countries){
        countries.add(new Country(x, y));
        for(int[] d : dir){
            int nx = x + d[0];
            int ny = y + d[1];
            if(isValid(map[x][y], nx, ny)){
                visited[nx][ny] = true;
                findUnion(nx, ny, countries);
            }
        }
    }

    public static boolean isValid(int val, int nx, int ny){
        if(nx &amp;lt; 0 || ny &amp;lt; 0 || nx &amp;gt;= N || ny &amp;gt;= N) return false;
        if(visited[nx][ny]) return false;
        int diff = Math.abs(val-map[nx][ny]);
        if(diff &amp;gt;= L &amp;amp;&amp;amp; diff &amp;lt;= R) return true;
        return false;
    }

}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Python&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Recursion Error와 80%에서 시간초과&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;import sys&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sys.setrecursionlimit(10**5)&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 추가 후 pypy3로 제출&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1668829822715&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import sys

sys.setrecursionlimit(10**5)

n, l, r = map(int, input().split())
board = []
for i in range(n):
    board.append(list(map(int, input().split())))

dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]
checked = [[False]*n for _ in range(n)]

def dfs(board, union, checked, x, y):
    checked[x][y] = True
    for i in range(4):
        nx = x + dx[i]
        ny = y + dy[i]
        if nx &amp;lt; 0 or ny &amp;lt; 0 or nx &amp;gt;= n or ny &amp;gt;= n or checked[nx][ny]:
            continue
        if l &amp;lt;= abs(board[x][y] - board[nx][ny]) &amp;lt;= r:
            union.append((nx, ny))
            dfs(board, union, checked, nx, ny)

day = 0
while True:
    unions = []
    checked = [[False] * n for _ in range(n)]

    for i in range(n):
        for j in range(n):
            if not checked[i][j]:
                union = [(i, j)]
                dfs(board, union, checked, i, j)
                unions.append(union)

    # board 인구수 업데이트
    if len(unions) == n*n:
        break
    else:
        day += 1
        for union in unions:
            people_count = 0
            for nation in union:
                x, y = nation
                people_count += board[x][y]
            updated_count = int(people_count//len(union))
            for nation in union:
                x, y = nation
                board[x][y] = updated_count

print(day)&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/BOJ</category>
      <category>DFS</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/227</guid>
      <comments>https://gom20.tistory.com/227#entry227comment</comments>
      <pubDate>Thu, 23 Dec 2021 18:45:34 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 2485] 가로수 (Java)</title>
      <link>https://gom20.tistory.com/226</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2485&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/2485&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1640081456495&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;2485번: 가로수&quot; data-og-description=&quot;첫째 줄에는 이미 심어져 있는 가로수의 수를 나타내는 하나의 정수 N이 주어진다(3 &amp;le; N &amp;le; 100,000). 둘째 줄부터 N개의 줄에는 각 줄마다 심어져 있는 가로수의 위치가 양의 정수로 주어지며, 가&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/2485&quot; data-og-url=&quot;https://www.acmicpc.net/problem/2485&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bAfZTa/hyMMTMJDgX/bY7YMFXvlYAcJPkKSWFYk0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2485&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/2485&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bAfZTa/hyMMTMJDgX/bY7YMFXvlYAcJPkKSWFYk0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;2485번: 가로수&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫째 줄에는 이미 심어져 있는 가로수의 수를 나타내는 하나의 정수 N이 주어진다(3 &amp;le; N &amp;le; 100,000). 둘째 줄부터 N개의 줄에는 각 줄마다 심어져 있는 가로수의 위치가 양의 정수로 주어지며, 가&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&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을 더한 값이 가로수의 개수가 된다.&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1640081444539&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package math;

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class BOJ2485 {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine());
        int[] arr = new int[N];

        int min = Integer.MAX_VALUE;
        int max = Integer.MIN_VALUE;
        for(int i = 0; i &amp;lt; N; i++){
            arr[i] = Integer.parseInt(br.readLine());
            min = Math.min(arr[i], min);
            max = Math.max(arr[i], max);
        }
        int[] interval = new int[N-1];
        for(int i = 0; i &amp;lt; N-1; i++){
            interval[i] = arr[i+1] - arr[i];
        }

        int gcd = getGCD(interval[0], interval[1]);
        for(int i = 2; i &amp;lt; N-1; i++){
            gcd = getGCD(gcd, interval[i]);
        }

        System.out.println(((max-min)/gcd)+1 - (arr.length));
    }

    public static int getGCD(int a, int b){
        // great common divisor
        if(a &amp;lt; b){
            int temp = b;
            b = a;
            a = temp;
        }

        while(b != 0){
            int r = a%b;
            a = b;
            b = r;
        }
        return a;
    }

}&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/BOJ</category>
      <category>gcd</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/226</guid>
      <comments>https://gom20.tistory.com/226#entry226comment</comments>
      <pubDate>Tue, 21 Dec 2021 19:15:43 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 15683] 감시 (Java)</title>
      <link>https://gom20.tistory.com/225</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/15683&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/15683&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1639975266270&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;15683번: 감시&quot; data-og-description=&quot;스타트링크의 사무실은 1&amp;times;1크기의 정사각형으로 나누어져 있는 N&amp;times;M 크기의 직사각형으로 나타낼 수 있다. 사무실에는 총 K개의 CCTV가 설치되어져 있는데, CCTV는&amp;nbsp;5가지 종류가 있다. 각 CCTV가 감&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/15683&quot; data-og-url=&quot;https://www.acmicpc.net/problem/15683&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/F1O0T/hyMKHePpOV/Eoobk1DNjLP4e4EeLmHIhk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/15683&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/15683&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/F1O0T/hyMKHePpOV/Eoobk1DNjLP4e4EeLmHIhk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;15683번: 감시&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;스타트링크의 사무실은 1&amp;times;1크기의 정사각형으로 나누어져 있는 N&amp;times;M 크기의 직사각형으로 나타낼 수 있다. 사무실에는 총 K개의 CCTV가 설치되어져 있는데, CCTV는&amp;nbsp;5가지 종류가 있다. 각 CCTV가 감&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;753&quot; data-origin-height=&quot;216&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLlhZO/btrofEUO9jw/iCLdLGk7umc4XsIWAAiu6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLlhZO/btrofEUO9jw/iCLdLGk7umc4XsIWAAiu6k/img.png&quot; data-alt=&quot;BOJ 15683&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLlhZO/btrofEUO9jw/iCLdLGk7umc4XsIWAAiu6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLlhZO%2FbtrofEUO9jw%2FiCLdLGk7umc4XsIWAAiu6k%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;753&quot; height=&quot;216&quot; data-origin-width=&quot;753&quot; data-origin-height=&quot;216&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BOJ 15683&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;삼성 문제의 경우 BruteForce 유형이 많은 것 같다.&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;모든 경우의 수를 조합하여 사각 지대의 최소 개수를 구한다.&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;1. 감시카메라 타입 별로 가능한 방향을 미리 정의한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 방향에 따른 좌표 증/감분을 미리 정의한다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1639975816711&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    static HashMap&amp;lt;Integer, char[][]&amp;gt; possibleDir = new HashMap&amp;lt;Integer, char[][]&amp;gt;(){{
        put(1, new char[][]{{'L'}, {'R'}, {'U'}, {'D'}});
        put(2, new char[][]{{'L', 'R'}, {'U', 'D'}});
        put(3, new char[][]{{'U','R'}, {'R', 'D'}, {'D', 'L'}, {'L', 'U'}});
        put(4, new char[][]{{'U', 'R', 'D'}, {'R', 'D', 'L'}, {'D', 'L', 'U'}, {'L', 'U', 'R'}});
        put(5, new char[][]{{'L', 'R', 'U', 'D'}});
    }};

    static HashMap&amp;lt;Character, int[]&amp;gt; direction = new HashMap&amp;lt;Character, int[]&amp;gt;(){{
        put('R', new int[]{0, 1});
        put('L', new int[]{0, -1});
        put('U', new int[]{-1, 0});
        put('D', new int[]{1, 0});
    }};&lt;/code&gt;&lt;/pre&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. Map을 저장한다. 이 때, 감시카메라 타입과 좌표는 따로 List에 담아 둔다.&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;markdown&quot;&gt;&lt;code&gt;map = new int[N][M];
for(int i = 0; i &amp;lt; N; i++){
    st = new StringTokenizer(br.readLine());
    for(int j = 0; j &amp;lt; M; j++){
        map[i][j] = Integer.parseInt(st.nextToken());
        if(map[i][j] &amp;gt;= 1 &amp;amp;&amp;amp; map[i][j] &amp;lt;= 5){
            list.add(new Node(map[i][j], i, j));
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 재귀함수를 이용해 감시 카메라의 방향을 선택하는 모든 경우의 수를 체크한다.&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;recur(0);&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;public static void recur(int idx){
    if(idx == list.size()){
        // calculate
        int[][] cloneMap = cloneMap();
        for(Node node : selected){
            for(char d : node.dir){
                checkMap(cloneMap, node.x, node.y, d);
            }
        }
        answer = Math.min(answer, getZeroCount(cloneMap));
        return;
    }

    Node node = list.get(idx);
    for(char[] dir : possibleDir.get(node.type)){
        node.dir = dir;
        selected.add(node);
        recur(idx+1);
        selected.remove(node);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 모든 감시 카메라의 방향이 선택 되었을 때, 사각지대의 개수를 계산한다.&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;public static void checkMap(int[][] cloneMap, int x, int y, char d){
    int nx = x + direction.get(d)[0];
    int ny = y + direction.get(d)[1];

    if(nx &amp;lt; 0 || ny &amp;lt; 0 || nx &amp;gt;= N || ny &amp;gt;= M) return;
    if(map[nx][ny] == 6) return;
    if(map[nx][ny] == 0) {
        cloneMap[nx][ny] = -1;
    }
    checkMap(cloneMap, nx, ny, d);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. 사각지대의 최소 값을 갱신한다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1639976059072&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;answer = Math.min(answer, getZeroCount(cloneMap));&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;package simulation;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.StringTokenizer;

public class BOJ15683 {

    static class Node {
        int type;
        char[] dir;
        int x;
        int y;
        public Node(int type, int x, int y){
            this.type = type;
            this.x = x;
            this.y = y;
        }
    }

    static int N, M;
    static int[][] map;
    static HashMap&amp;lt;Integer, char[][]&amp;gt; possibleDir = new HashMap&amp;lt;Integer, char[][]&amp;gt;(){{
        put(1, new char[][]{{'L'}, {'R'}, {'U'}, {'D'}});
        put(2, new char[][]{{'L', 'R'}, {'U', 'D'}});
        put(3, new char[][]{{'U','R'}, {'R', 'D'}, {'D', 'L'}, {'L', 'U'}});
        put(4, new char[][]{{'U', 'R', 'D'}, {'R', 'D', 'L'}, {'D', 'L', 'U'}, {'L', 'U', 'R'}});
        put(5, new char[][]{{'L', 'R', 'U', 'D'}});
    }};

    static HashMap&amp;lt;Character, int[]&amp;gt; direction = new HashMap&amp;lt;Character, int[]&amp;gt;(){{
        put('R', new int[]{0, 1});
        put('L', new int[]{0, -1});
        put('U', new int[]{-1, 0});
        put('D', new int[]{1, 0});
    }};

    static ArrayList&amp;lt;Node&amp;gt; list = new ArrayList&amp;lt;Node&amp;gt;();
    static ArrayList&amp;lt;Node&amp;gt; selected = new ArrayList&amp;lt;Node&amp;gt;();
    static int answer = Integer.MAX_VALUE;
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        map = new int[N][M];
        for(int i = 0; i &amp;lt; N; i++){
            st = new StringTokenizer(br.readLine());
            for(int j = 0; j &amp;lt; M; j++){
                map[i][j] = Integer.parseInt(st.nextToken());
                if(map[i][j] &amp;gt;= 1 &amp;amp;&amp;amp; map[i][j] &amp;lt;= 5){
                    list.add(new Node(map[i][j], i, j));
                }
            }
        }

        recur(0);

        System.out.println(answer);
    }

    public static int[][] cloneMap(){
        int[][] cloneMap = new int[N][M];
        for(int i = 0; i &amp;lt; N; i++){
            cloneMap[i] = map[i].clone();
        }
        return cloneMap;
    }

    public static int getZeroCount(int[][] cloneMap){
        int count = 0;
        for(int i = 0; i &amp;lt; N; i++){
            for(int j = 0; j &amp;lt; M; j++){
                if(cloneMap[i][j] == 0) count++;
            }
        }
        return count;
    }

    public static void checkMap(int[][] cloneMap, int x, int y, char d){
        int nx = x + direction.get(d)[0];
        int ny = y + direction.get(d)[1];

        if(nx &amp;lt; 0 || ny &amp;lt; 0 || nx &amp;gt;= N || ny &amp;gt;= M) return;
        if(map[nx][ny] == 6) return;
        if(map[nx][ny] == 0) {
            cloneMap[nx][ny] = -1;
        }
        checkMap(cloneMap, nx, ny, d);
    }

    public static void printMap(int[][] cloneMap){
        for(int i = 0; i &amp;lt; N; i++){
            for(int j = 0; j &amp;lt; M; j++){
                System.out.print(cloneMap[i][j] + &quot; &quot;);
            }
            System.out.println();
        }
    }

    public static void recur(int idx){
        if(idx == list.size()){
            // calculate
            int[][] cloneMap = cloneMap();
            for(Node node : selected){
                for(char d : node.dir){
                    checkMap(cloneMap, node.x, node.y, d);
                }
            }
            answer = Math.min(answer, getZeroCount(cloneMap));
            return;
        }

        Node node = list.get(idx);
        for(char[] dir : possibleDir.get(node.type)){
            node.dir = dir;
            selected.add(node);
            recur(idx+1);
            selected.remove(node);
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category> Problem Solving/BOJ</category>
      <category>bruteforce</category>
      <category>재귀함수</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/225</guid>
      <comments>https://gom20.tistory.com/225#entry225comment</comments>
      <pubDate>Mon, 20 Dec 2021 13:55:35 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 17070] 파이프 옮기기 1 (Java)</title>
      <link>https://gom20.tistory.com/224</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/17070&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/17070&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1639882848395&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;17070번: 파이프 옮기기 1&quot; data-og-description=&quot;유현이가 새 집으로 이사했다. 새 집의 크기는 N&amp;times;N의 격자판으로 나타낼 수 있고, 1&amp;times;1크기의 정사각형 칸으로 나누어져 있다. 각각의 칸은 (r, c)로 나타낼 수 있다. 여기서 r은 행의 번호, c는 열의&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/17070&quot; data-og-url=&quot;https://www.acmicpc.net/problem/17070&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bIx7NY/hyMKORz2jH/AQrAkmBJunHKGVqkoaSbX1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/17070&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/17070&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bIx7NY/hyMKORz2jH/AQrAkmBJunHKGVqkoaSbX1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;17070번: 파이프 옮기기 1&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;유현이가 새 집으로 이사했다. 새 집의 크기는 N&amp;times;N의 격자판으로 나타낼 수 있고, 1&amp;times;1크기의 정사각형 칸으로 나누어져 있다. 각각의 칸은 (r, c)로 나타낼 수 있다. 여기서 r은 행의 번호, c는 열의&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 진출 방향에 따른 x, y 좌표 증가분을 미리 정의해 둔다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 현재 파이프의 방향에 따라 진출 가능한 방향을 미리 정의해둔다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1639882920223&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    static HashMap&amp;lt;Character, int[]&amp;gt; dir = new HashMap&amp;lt;Character, int[]&amp;gt;(){{
        put('V', new int[]{1, 0});
        put('H', new int[]{0, 1});
        put('D', new int[]{1, 1});
    }};
    static HashMap&amp;lt;Character, List&amp;lt;Character&amp;gt;&amp;gt; possibleDir = new HashMap&amp;lt;Character, List&amp;lt;Character&amp;gt;&amp;gt;(){{
        put('V', Arrays.asList('V', 'D'));
        put('H', Arrays.asList('H', 'D'));
        put('D', Arrays.asList('V', 'H', 'D'));
    }};&lt;/code&gt;&lt;/pre&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. dfs 를 진행한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좌표가 N, N일 때 count를 증가시킨다.&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;pre id=&quot;code_1639882954954&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    public static void dfs(int x, int y, char cur){
        if(x == N &amp;amp;&amp;amp; y == N){
            answer++;
            return;
        }
        for(char nDir : possibleDir.get(cur)){
            int nx = x + dir.get(nDir)[0];
            int ny = y + dir.get(nDir)[1];
            if(isValid(nx, ny, nDir)){
                dfs(nx, ny, nDir);
            }
        }
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. isValid 코드&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;pre id=&quot;code_1639883062100&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    public static boolean isValid(int nx, int ny, char nDir){
        if(nx &amp;lt; 1 || ny &amp;lt; 1|| nx &amp;gt; N || ny &amp;gt; N) return false;
        if(nDir == 'D'){
            if(map[nx][ny] == 0 &amp;amp;&amp;amp; map[nx][ny-1] == 0 &amp;amp;&amp;amp; map[nx-1][ny] == 0) return true;
        } else {
            if (map[nx][ny] == 0) return true;
        }
        return false;
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1639882851234&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package dfs;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.StringTokenizer;

public class BOJ17070 {

    static HashMap&amp;lt;Character, int[]&amp;gt; dir = new HashMap&amp;lt;Character, int[]&amp;gt;(){{
        put('V', new int[]{1, 0});
        put('H', new int[]{0, 1});
        put('D', new int[]{1, 1});
    }};
    static HashMap&amp;lt;Character, List&amp;lt;Character&amp;gt;&amp;gt; possibleDir = new HashMap&amp;lt;Character, List&amp;lt;Character&amp;gt;&amp;gt;(){{
        put('V', Arrays.asList('V', 'D'));
        put('H', Arrays.asList('H', 'D'));
        put('D', Arrays.asList('V', 'H', 'D'));
    }};

    static int N, answer;
    static int[][] map;
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        N = Integer.parseInt(br.readLine());
        map = new int[N+1][N+1];
        StringTokenizer st = null;
        for(int i = 1; i &amp;lt;= N; i++){
            st = new StringTokenizer(br.readLine());
            for(int j = 1; j &amp;lt;= N; j++){
                map[i][j] = Integer.parseInt(st.nextToken());
            }
        }
        dfs(1, 2, 'H');
        System.out.println(answer);
    }

    public static void dfs(int x, int y, char cur){
        if(x == N &amp;amp;&amp;amp; y == N){
            answer++;
            return;
        }
        for(char nDir : possibleDir.get(cur)){
            int nx = x + dir.get(nDir)[0];
            int ny = y + dir.get(nDir)[1];
            if(isValid(nx, ny, nDir)){
                dfs(nx, ny, nDir);
            }
        }
    }

    public static boolean isValid(int nx, int ny, char nDir){
        if(nx &amp;lt; 1 || ny &amp;lt; 1|| nx &amp;gt; N || ny &amp;gt; N) return false;
        if(nDir == 'D'){
            if(map[nx][ny] == 0 &amp;amp;&amp;amp; map[nx][ny-1] == 0 &amp;amp;&amp;amp; map[nx-1][ny] == 0) return true;
        } else {
            if (map[nx][ny] == 0) return true;
        }
        return false;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/BOJ</category>
      <category>DFS</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/224</guid>
      <comments>https://gom20.tistory.com/224#entry224comment</comments>
      <pubDate>Sun, 19 Dec 2021 12:05:48 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 16236] 아기 상어 (Java)</title>
      <link>https://gom20.tistory.com/223</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/16236&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/16236&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1639823185373&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;16236번: 아기 상어&quot; data-og-description=&quot;N&amp;times;N 크기의 공간에 물고기 M마리와 아기 상어 1마리가 있다. 공간은 1&amp;times;1 크기의 정사각형 칸으로 나누어져 있다. 한 칸에는 물고기가 최대 1마리 존재한다. 아기 상어와 물고기는 모두 크기를 가&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/16236&quot; data-og-url=&quot;https://www.acmicpc.net/problem/16236&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bc6OXS/hyMKFs46Rl/5SZKKy44qWvbTjr3xMPTm1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/16236&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/16236&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bc6OXS/hyMKFs46Rl/5SZKKy44qWvbTjr3xMPTm1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;16236번: 아기 상어&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;N&amp;times;N 크기의 공간에 물고기 M마리와 아기 상어 1마리가 있다. 공간은 1&amp;times;1 크기의 정사각형 칸으로 나누어져 있다. 한 칸에는 물고기가 최대 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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 문제의 기본 접근 방법은 BFS이다.&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;만약 있다면 BFS를 진행한다.&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;BFS를 진행하면서 핵심 포인트는,&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;동일 depth에 있는 칸을 체크하여 먹을 수 있는 물고기 좌표를 모두 저장해 놓고 탐색을 종료하는 것이다.&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;상어 사이즈가 커지는 것도 문제를 대충 읽어서 한참 헤멨다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1639823189961&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package simulation;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;

public class BOJ16236 {

    public static int[][] dir = new int[][]{{-1, 0}, {0, -1}, {0, 1}, {1, 0}};
    public static int[][] map;
    public static int N, babySize, bx, by, answer, foundDepth, fishCnt;
    public static ArrayList&amp;lt;int[]&amp;gt; fishlist;
    public static HashSet&amp;lt;String&amp;gt; checked;
    public static boolean[][] visited;
    public static void main(String[] args) throws Exception {
        // 물고기 M, 상어 1마리
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        N = Integer.parseInt(br.readLine());
        map = new int[N][N];
        babySize = 2;
        StringTokenizer st = null;
        for(int i = 0 ; i &amp;lt; N; i++){
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j &amp;lt; N; j++){
                map[i][j] = Integer.parseInt(st.nextToken());
                if(map[i][j] == 9){
                    bx = i;
                    by = j;
                }
            }
        }

        checked = new HashSet&amp;lt;String&amp;gt;();
        fishlist = new ArrayList&amp;lt;int[]&amp;gt;();
        map[bx][by] = 0;
        while(true){
            if(isExistFishToEat()){
                visited = new boolean[N][N];
                foundDepth = Integer.MAX_VALUE;
                checked.clear();
                fishlist.clear();

                visited[bx][by] = true;
                bfs(bx, by);
                Collections.sort(fishlist, new Comparator&amp;lt;int[]&amp;gt;() {
                    @Override
                    public int compare(int[] o1, int[] o2) {
                        int rs = o1[0] - o2[0];
                        if(rs == 0) rs = o1[1] - o2[1];
                        return rs;
                    }
                });
                if(fishlist.isEmpty()) break;
                int fx = fishlist.get(0)[0];
                int fy = fishlist.get(0)[1];
                map[fx][fy] = 0;
                bx = fx;
                by = fy;
                fishCnt++;

                while(fishCnt &amp;gt;= babySize) {
                    fishCnt = fishCnt-babySize;
                    babySize++;
                }
                answer += foundDepth;
            } else {
                break;
            }
        }

        System.out.println(answer);
    }

    public static void bfs(int sx, int sy){
        Queue&amp;lt;Integer&amp;gt; que = new LinkedList&amp;lt;Integer&amp;gt;();
        que.offer(sx);
        que.offer(sy);
        que.offer(0);

        while(!que.isEmpty()){
            int x = que.poll();
            int y = que.poll();
            int depth = que.poll();

            if(foundDepth &amp;lt; depth) break;
            if(1 &amp;lt;= map[x][y] &amp;amp;&amp;amp; map[x][y] &amp;lt;= 6 &amp;amp;&amp;amp; map[x][y] &amp;lt; babySize){
                // 먹을 수 있는 물고기 등장!
                if(checked.contains(x + &quot;,&quot; + y)) continue;
                checked.add(x + &quot;,&quot; + y);
                fishlist.add(new int[]{x, y});
                foundDepth = depth;
            }
            for(int[] d : dir){
                int nx = x + d[0];
                int ny = y + d[1];
                int nDepth = depth + 1;
                if(isValid(nx, ny)){
                    visited[nx][ny] = true;
                    que.offer(nx);
                    que.offer(ny);
                    que.offer(nDepth);
                }
            }
        }
    }

    public static boolean isValid(int x, int y){
        if(x &amp;lt; 0 || y &amp;lt; 0 || x &amp;gt;= N || y &amp;gt;= N) return false;
        if(map[x][y] &amp;gt; babySize) return false;
        if(visited[x][y]) return false;
        return true;
    }

    public static boolean isExistFishToEat(){
        int cnt = 0;
        for(int i = 0; i &amp;lt; N; i++){
            for(int j = 0; j &amp;lt; N; j++){
                if(i == bx &amp;amp;&amp;amp; j == by) continue;
                if(1 &amp;lt;= map[i][j] &amp;amp;&amp;amp; map[i][j] &amp;lt;= 6 &amp;amp;&amp;amp; map[i][j] &amp;lt; babySize){
                    cnt++;
                }
            }
        }
        return cnt &amp;gt; 0 ? true : false;
    }

}&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/BOJ</category>
      <category>BFS</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/223</guid>
      <comments>https://gom20.tistory.com/223#entry223comment</comments>
      <pubDate>Sat, 18 Dec 2021 19:31:23 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 2468] 안전 영역 (Java)</title>
      <link>https://gom20.tistory.com/222</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2468&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/2468&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1639709284689&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;2468번: 안전 영역&quot; data-og-description=&quot;재난방재청에서는 많은 비가 내리는 장마철에 대비해서 다음과 같은 일을 계획하고 있다. 먼저 어떤 지역의 높이 정보를 파악한다. 그 다음에 그 지역에 많은 비가 내렸을 때 물에 잠기지 않는 &quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/2468&quot; data-og-url=&quot;https://www.acmicpc.net/problem/2468&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ecqaHP/hyMI3CL7Yr/05X4YytehYtSVujIVUk9R0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2468&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/2468&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ecqaHP/hyMI3CL7Yr/05X4YytehYtSVujIVUk9R0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;2468번: 안전 영역&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DFS + BruteForce&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;각 강수량마다 safe영역을 구하면서, max값을 갱신&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1639709277245&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package dfs;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class BOJ2468 {
    public static int[][] map;
    public static boolean[][] safeArea;
    public static int N;
    public static int[][] dir = new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        N = Integer.parseInt(br.readLine());
        map = new int[N][N];
        safeArea = new boolean[N][N];
        StringTokenizer st = null;
        for(int i = 0; i &amp;lt; N; i++){
            st = new StringTokenizer(br.readLine());
            for(int j = 0; j &amp;lt; N; j++){
                map[i][j] = Integer.parseInt(st.nextToken());
            }
        }
        int answer = 1;
        for(int k = 1; k &amp;lt;= 100; k++){
            safeArea = new boolean[N][N];
            for(int i = 0; i &amp;lt; N; i++){
                for(int j = 0; j &amp;lt; N; j++){
                    if(map[i][j] &amp;gt; k) safeArea[i][j] = true;
                }
            }
            answer = Math.max(answer, getSafeAreaCount());
        }

        System.out.println(answer);
    }

    public static int getSafeAreaCount(){
        int cnt = 0;
        for(int i = 0; i &amp;lt; N; i++){
           for(int j = 0; j &amp;lt; N;j++){
               if(safeArea[i][j]){
                   dfs(i, j);
                   cnt++;
               }
           }
        }
       return cnt;
    }

    public static void dfs(int x, int y){
        safeArea[x][y] = false;
        for(int[]d : dir){
            int nx = x + d[0];
            int ny = y + d[1];
            if(isValid(nx, ny)){
                dfs(nx, ny);
            }
        }
    }

    public static boolean isValid(int x, int y){
        if(x &amp;lt; 0 || y &amp;lt; 0 || x &amp;gt;= N || y &amp;gt;= N) return false;
        if(!safeArea[x][y]) return false;
        return true;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/BOJ</category>
      <category>DFS</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/222</guid>
      <comments>https://gom20.tistory.com/222#entry222comment</comments>
      <pubDate>Fri, 17 Dec 2021 11:49:27 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 14503] 로봇 청소기 (Java)</title>
      <link>https://gom20.tistory.com/221</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/14503&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/14503&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1639652256946&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;14503번: 로봇 청소기&quot; data-og-description=&quot;로봇 청소기가 주어졌을 때, 청소하는 영역의 개수를 구하는 프로그램을 작성하시오. 로봇 청소기가 있는 장소는 N&amp;times;M 크기의 직사각형으로 나타낼 수 있으며, 1&amp;times;1크기의 정사각형 칸으로 나누어&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/14503&quot; data-og-url=&quot;https://www.acmicpc.net/problem/14503&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/hUbta/hyMJFmoW8K/tIbF3p6ir0k3RTid0PyUr1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/14503&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/14503&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/hUbta/hyMJFmoW8K/tIbF3p6ir0k3RTid0PyUr1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;14503번: 로봇 청소기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;로봇 청소기가 주어졌을 때, 청소하는 영역의 개수를 구하는 프로그램을 작성하시오. 로봇 청소기가 있는 장소는 N&amp;times;M 크기의 직사각형으로 나타낼 수 있으며, 1&amp;times;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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;dfs + 구현 문제이다.&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1639652305488&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package simulation;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class BOJ14503 {
    static int[][] map;
    static boolean[][] visited;
    // 0 북, 1 동, 2, 남, 3, 서
    static int[] rotation = new int[]{3, 0, 1, 2};
    static int[][] leftMove = new int[][]{{0, -1}, {-1, 0}, {0, 1}, {1, 0}};
    static int[][] backMove = new int[][]{{1, 0}, {0, -1}, {-1, 0}, {0, 1}};
    static int N, M;
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());

        st = new StringTokenizer(br.readLine());
        int x = Integer.parseInt(st.nextToken());
        int y = Integer.parseInt(st.nextToken());
        int dir = Integer.parseInt(st.nextToken());

        map = new int[N][M];
        visited = new boolean[N][M];
        for(int i = 0; i &amp;lt; N; i++){
            st = new StringTokenizer(br.readLine());
            for(int j = 0; j &amp;lt; M; j++){
                map[i][j] = Integer.parseInt(st.nextToken());
            }
        }
        // 1. 현재 위치를 청소한다.
        visited[x][y] = true;
        // 2. 현재 위치에서 현재 방향을 기준으로 왼쪽 방향부터 차례대로 인접한 칸을 탐색한다.
        dfs(x, y, dir);
    }

    public static void printAnswer(){
        int answer = 0;
        for(int i = 0; i &amp;lt; visited.length; i++){
            for(int j = 0; j &amp;lt; visited[i].length; j++){
                if(visited[i][j]) answer++;
            }
        }
        System.out.println(answer);
    }

    public static void dfs(int x, int y, int dir){

        // 네 방향 모두 청소가 되어있거나 벽인가?
        boolean isCompleted = true;
        for(int[] d : leftMove){
            int nx = x + d[0];
            int ny = y + d[1];
            if(isValid(nx, ny) &amp;amp;&amp;amp; map[nx][ny] == 0 &amp;amp;&amp;amp; !visited[nx][ny]){
                isCompleted = false;
            }
        }
        if(isCompleted) {
            int nx = x + backMove[dir][0];
            int ny = y + backMove[dir][1];
            // 네 방향 모두 청소가 이미 되어있거나 벽이면서,
            // 뒤쪽 방향이 벽이라 후진도 할 수 없는 경우에는 작동을 멈춘다.
            if(isValid(nx, ny) &amp;amp;&amp;amp; map[nx][ny] == 1){
                printAnswer();
                System.exit(0);
            }
            dfs(nx, ny, dir);
        }

        // 왼쪽 방향에 아직 청소하지 않은 공간이 존재한다면,
        // 그 방향으로 회전한 다음 한 칸을 전진하고 1번부터 진행한다.
        int nx = x + leftMove[dir][0];
        int ny = y + leftMove[dir][1];

        if(isValid(nx, ny) &amp;amp;&amp;amp; map[nx][ny] == 0 &amp;amp;&amp;amp; !visited[nx][ny]){
            visited[nx][ny] = true;
            dfs(nx, ny, rotation[dir]);
        } else {
            dfs(x, y, rotation[dir]);
        }
    }

    public static boolean isValid(int x, int y){
        if(x &amp;lt; 0 || y &amp;lt; 0 || x &amp;gt;= N || y &amp;gt;= M) return false;
        return true;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/BOJ</category>
      <category>DFS</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/221</guid>
      <comments>https://gom20.tistory.com/221#entry221comment</comments>
      <pubDate>Thu, 16 Dec 2021 19:58:44 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 14501] 퇴사 (Java)</title>
      <link>https://gom20.tistory.com/220</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/14501&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/14501&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1639534410796&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;14501번: 퇴사&quot; data-og-description=&quot;첫째 줄에 백준이가 얻을 수 있는 최대 이익을 출력한다.&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/14501&quot; data-og-url=&quot;https://www.acmicpc.net/problem/14501&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bbOHIx/hyMH3hhArX/EAQ8ZgyW7d6tjtrM57pJvK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/14501&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/14501&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bbOHIx/hyMH3hhArX/EAQ8ZgyW7d6tjtrM57pJvK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;14501번: 퇴사&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;N의 범위가 작기 때문에 완전 탐색으로 접근하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상담 건을 선택 한 후, profit을 증가하여 다음 가능한 상담을 선택한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상담 일수가 초과되거나 종료되었을 때의 profit의 합을 max값과 비교하여 갱신한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1639534436476&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package bruteforce;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class BOJ14501 {
    public static int[] T, P, dp;
    public static int N;
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        N = Integer.parseInt(br.readLine());
        T = new int[N+1];
        P = new int[N+1];
        dp = new int[N+1];
        StringTokenizer st = null;
        for(int i = 1; i &amp;lt;= N; i++){
            st = new StringTokenizer(br.readLine());
            T[i] = Integer.parseInt(st.nextToken());
            P[i] = Integer.parseInt(st.nextToken());
        }

        for(int i = 1; i &amp;lt;= N; i++){
            recur(i, T[i], P[i], 0);
        }
        System.out.println(max);
    }

    public static int max = 0;
    public static void recur(int day, int time, int profit, int total){
        if(day + time &amp;gt;= N+1) {
            // 끝
            if(day + time == N+1){
                total += profit;
            }
            max = Math.max(max, total);
            return;
        }

        for(int i = day + time; i &amp;lt;= N; i++){
            recur(i, T[i], P[i], total+profit);
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Python&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DP방식&lt;/p&gt;
&lt;pre class=&quot;vim&quot;&gt;&lt;code&gt;n = int(input())
t, p = [0]*n, [0]*n

for i in range(n):
    t[i], p[i] = map(int, input().split())

#dp[i]는 i일부터 마지막날까지 얻을수 있는 최대 상담 이윤

max_value = 0
dp = [0]*(n+1)
for i in range(n-1, -1, -1):
    if i + t[i] &amp;lt;= n:
        max_value = max(p[i] + dp[i+t[i]], max_value)
        dp[i] = max_value
    else:
        dp[i] = max_value

print(max_value)&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/BOJ</category>
      <category>brute force</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/220</guid>
      <comments>https://gom20.tistory.com/220#entry220comment</comments>
      <pubDate>Wed, 15 Dec 2021 11:15:44 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 2636] 치즈 (Java)</title>
      <link>https://gom20.tistory.com/219</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2636&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/2636&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1639400035392&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;2636번: 치즈&quot; data-og-description=&quot;아래 &amp;lt;그림 1&amp;gt;과 같이 정사각형 칸들로 이루어진 사각형 모양의 판이 있고, 그 위에 얇은 치즈(회색으로 표시된 부분)가 놓여 있다. 판의 가장자리(&amp;lt;그림 1&amp;gt;에서 네모 칸에 X친 부분)에는 치즈가 놓&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/2636&quot; data-og-url=&quot;https://www.acmicpc.net/problem/2636&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/UvAf2/hyMFSVEMSw/gLcYLul7xYK8jkPa4NbpXk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2636&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/2636&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/UvAf2/hyMFSVEMSw/gLcYLul7xYK8jkPa4NbpXk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;2636번: 치즈&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;아래 &amp;lt;그림 1&amp;gt;과 같이 정사각형 칸들로 이루어진 사각형 모양의 판이 있고, 그 위에 얇은 치즈(회색으로 표시된 부분)가 놓여 있다. 판의 가장자리(&amp;lt;그림 1&amp;gt;에서 네모 칸에 X친 부분)에는 치즈가 놓&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;치즈 내부 구멍과 외부 공기 모두 0으로 표시되기 때문에 이를 구분해야 한다.&amp;nbsp;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;1. 내부 구멍과 외부 공기를 구분한다. &lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;전체 맵의 가장 자리가 비어있기 때문에 첫 번째 좌표 0, 0에서 BFS하여 상하좌우 0인 좌표를 모두 3으로 변경해주었다. 즉, 외부 공기를 3으로 바꿔주었다.&lt;/li&gt;
&lt;/ul&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;2. 치즈의 공기 접촉면을 체크한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;맵을 순회하면서 값이 3(외부 공기)일 때, 상하좌우 인접 좌표에 1(치즈)가 있다면 해당 치즈는 공기와 접촉된 치즈임을 알수 있도록 (공기 접촉 치즈) 2로 변경한다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;맵에서 1(치즈)의 count를 구한다&lt;/li&gt;
&lt;li&gt;2(공기 접촉 치즈)를 3(외부 공기)으로 변경한다. (치즈를 녹이는 행위)&lt;/li&gt;
&lt;li&gt;3(외부 공기)일 경우 상하 좌우 0(내부 구멍)을 체크하여 BFS로 3(외부 공기)으로 변경해준다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1639400040406&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package bfs;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class BOJ2636 {

    public static int N, M;
    public static int[][] map;
    public static int[][] dir = new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());

        int hour = 0;
        int lastCnt = 0;

        map = new int[N][M];
        for(int i = 0; i &amp;lt; N; i++){
            st = new StringTokenizer(br.readLine());
            for(int j = 0; j &amp;lt; M; j++){
                map[i][j] = Integer.parseInt(st.nextToken());
                if(map[i][j] == 1) lastCnt++;
            }
        }
        map[0][0] = 3;
        bfs(0, 0);

        while(true){
            // Boundary -&amp;gt; 2로 바꾸기
            checkBoundary();

            // 남은 치즈 개수 구하기
            // 2 -&amp;gt; 3 으로 바꾸기
            // 3 이면 주변 0 있는지 체크해서 bfs
            int cnt = 0;
            for(int i = 0; i &amp;lt; N; i++){
                for(int j = 0; j &amp;lt; M; j++){
                    if(map[i][j] == 1){
                        cnt++;
                    } else if(map[i][j] == 2){
                        map[i][j] = 3;
                    }
                    if(map[i][j] == 3){
                        for(int[] d : dir){
                            int ni = i + d[0];
                            int nj = j + d[1];
                            if(isValid(ni, nj) &amp;amp;&amp;amp; isHole(ni, nj)){
                                map[ni][nj] = 3;
                                bfs(ni, nj);
                            }
                        }
                    }
                }
            }
            hour++;
            if(cnt &amp;gt; 0){
                lastCnt = cnt;
            }
            if(cnt == 0) break;
        }

        System.out.println(hour);
        System.out.println(lastCnt);
    }

    public static void checkBoundary(){
        // 3이면 상하좌우 탐색해서 1이면 2로 설정.
        for(int i = 0; i &amp;lt; N; i++){
            for(int j = 0; j &amp;lt; M; j++){
                if(map[i][j] == 3){
                    for(int[] d : dir){
                        int ni = i + d[0];
                        int nj = j + d[1];
                        if(isValid(ni, nj) &amp;amp;&amp;amp; isCheese(ni, nj)){
                            map[ni][nj] = 2;
                        }
                    }
                }
            }
        }
    }

    public static void bfs(int sx, int sy){
        Queue&amp;lt;Integer&amp;gt; que = new LinkedList&amp;lt;Integer&amp;gt;();
        que.offer(sx);
        que.offer(sy);

        while(!que.isEmpty()){
            int x = que.poll();
            int y = que.poll();

            for(int[] d : dir){
                int nx = x + d[0];
                int ny = y + d[1];
                if(isValid(nx, ny) &amp;amp;&amp;amp; isHole(nx, ny)){
                    map[nx][ny] = 3;
                    que.offer(nx);
                    que.offer(ny);
                }
            }
        }
    }

    public static boolean isValid(int x, int y){
        if(x &amp;lt; 0 || y &amp;lt; 0 || x &amp;gt;= N || y &amp;gt;= M ) return false;
        return true;
    }

    public static boolean isHole(int x, int y){
        if(map[x][y] == 0) return true;
        return false;
    }

    public static boolean isCheese(int x, int y){
        if(map[x][y] == 1) return true;
        return false;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/BOJ</category>
      <category>BFS</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/219</guid>
      <comments>https://gom20.tistory.com/219#entry219comment</comments>
      <pubDate>Mon, 13 Dec 2021 22:06:56 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 4195] 친구 네트워크 (Java)</title>
      <link>https://gom20.tistory.com/218</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/4195&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/4195&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1639284531506&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;4195번: 친구 네트워크&quot; data-og-description=&quot;첫째 줄에 테스트 케이스의 개수가 주어진다. 각 테스트 케이스의 첫째 줄에는 친구 관계의 수 F가 주어지며, 이 값은 100,000을 넘지 않는다. 다음 F개의 줄에는 친구 관계가 생긴 순서대로 주어진&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/4195&quot; data-og-url=&quot;https://www.acmicpc.net/problem/4195&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ctBqjE/hyMFS09dpq/X4XaWElz5wYwQCdFVRLfB1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/4195&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/4195&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ctBqjE/hyMFS09dpq/X4XaWElz5wYwQCdFVRLfB1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;4195번: 친구 네트워크&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫째 줄에 테스트 케이스의 개수가 주어진다. 각 테스트 케이스의 첫째 줄에는 친구 관계의 수 F가 주어지며, 이 값은 100,000을 넘지 않는다. 다음 F개의 줄에는 친구 관계가 생긴 순서대로 주어진&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;union-find 기법을 사용하여 풀 수 있다.&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. parent 정보와 네트워크 size 정보 담을 자료 구조를 생성한다.&lt;/p&gt;
&lt;pre id=&quot;code_1639284827562&quot; class=&quot;java&quot; style=&quot;display: block; overflow: auto; padding: 20px; color: #383a42; background: #f8f8f8; font-size: 14px; font-family: 'SF Mono', Menlo, Consolas, Monaco, monospace; border: 1px solid #ebebeb; line-height: 1.71; margin: 20px auto 0px; cursor: default; z-index: 1; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;        parent = new HashMap&amp;lt;String, String&amp;gt;(); // 루트 노드 정보
        setSize = new HashMap&amp;lt;String, Integer&amp;gt;(); // 집합의 사이즈&lt;/code&gt;&lt;/pre&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. 입력 전에는 어떤 값이 들어오는지 알 수 없으므로, 입력 받을 때마다 초기값을 할당한다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1639284827562&quot; class=&quot;java&quot; style=&quot;margin: 20px auto 0px; display: block; overflow: auto; padding: 20px; color: #383a42; background: #f8f8f8; font-size: 14px; font-family: 'SF Mono', Menlo, Consolas, Monaco, monospace; border: 1px solid #ebebeb; line-height: 1.71; cursor: default; z-index: 1;&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;            // 입력 받을 때 초기화
            if(!setSize.containsKey(a)) setSize.put(a, 1);
            if(!setSize.containsKey(b)) setSize.put(b, 1);
            if(!parent.containsKey(a)) parent.put(a, a);
            if(!parent.containsKey(b)) parent.put(b, b);&lt;/code&gt;&lt;/pre&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. 만약 두 친구가 동일한 네트워크에 있지 않을 경우, 동일한 네트워크로 합친다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1639284934119&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;            if(find(a) != find(b)){
                union(a, b);
            }&lt;/code&gt;&lt;/pre&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;span&gt;find함수 내 path-compression기법을 통해 각 노드의 parent에 루트 노드 값을 설정하고, 루트 노드 값을 얻어온다.&amp;nbsp;&lt;/span&gt;a, b 중 속한 집합의 사이즈가 큰 쪽으로 Union 한다. 각 네트워크의 루트 노드의 집합 사이즈를 갱신 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1639286949715&quot; class=&quot;java&quot; style=&quot;display: block; overflow: auto; padding: 20px; color: #383a42; background: #f8f8f8; font-size: 14px; font-family: 'SF Mono', Menlo, Consolas, Monaco, monospace; border: 1px solid #ebebeb; line-height: 1.71; margin: 20px auto 0px; cursor: default; z-index: 1; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    private static String find(String a){
        if(parent.get(a) == a) return a;
        parent.put(a, find(parent.get(a)));
        return parent.get(a);
    }
    
    private static void union(String a, String b){
        a = find(a);
        b = find(b);

        if(setSize.get(a) &amp;gt;= setSize.get(b)){
            parent.put(b, a);
            setSize.put(a, setSize.get(a) + setSize.get(b));
            setSize.put(b, 0);
        } else {
            parent.put(a, b);
            setSize.put(b, setSize.get(b) + setSize.get(a));
            setSize.put(a, 0);
        }
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 네트워크의 사이즈를 출력한다.&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;// a, b 친구 관계를 맺었으므로 한 명의 루트 노드에 대한 사이즈만 출력하면 됨
bw.write(setSize.get(find(a)) + &quot;\n&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;예제&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1639285019091&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;2
3
Fred Barney
Barney Betty
Betty Wilma
3
Fred Barney
Betty Wilma
Barney Betty&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;첫 번째 Test Case&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. Fred Barney 입력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;Parent&amp;gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 30%; height: 60px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Key&lt;/td&gt;
&lt;td&gt;Value&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fred&lt;/td&gt;
&lt;td&gt;Fred&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Barney&lt;/td&gt;
&lt;td&gt;Fred&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;setSize&amp;gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 30.3488%; height: 60px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 15.3488%; height: 20px;&quot;&gt;Key&lt;/td&gt;
&lt;td style=&quot;width: 15%; height: 20px;&quot;&gt;Value&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 15.3488%; height: 20px;&quot;&gt;Fred&lt;/td&gt;
&lt;td style=&quot;width: 15%; height: 20px;&quot;&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 15.3488%; height: 20px;&quot;&gt;Barney&lt;/td&gt;
&lt;td style=&quot;width: 15%; height: 20px;&quot;&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;Tree&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;474&quot; data-origin-height=&quot;511&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dusi8H/btrnHTcN6Fx/Z3EFTpmflqVk5gb5fWFb5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dusi8H/btrnHTcN6Fx/Z3EFTpmflqVk5gb5fWFb5k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dusi8H/btrnHTcN6Fx/Z3EFTpmflqVk5gb5fWFb5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdusi8H%2FbtrnHTcN6Fx%2FZ3EFTpmflqVk5gb5fWFb5k%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;210&quot; height=&quot;511&quot; data-origin-width=&quot;474&quot; data-origin-height=&quot;511&quot;/&gt;&lt;/span&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;size18&quot;&gt;2. Barney Betty 입력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;Parent&amp;gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 30%; height: 80px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;Key&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;Value&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;Fred&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;Fred&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;Barney&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;Fred&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;Betty&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;Fred&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;setSize&amp;gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 30.3488%; height: 60px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Key&lt;/td&gt;
&lt;td&gt;Value&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fred&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Barney&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Betty&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;Tree&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;511&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JcYLG/btrnByBbP3s/Uooo1Ko7MnS4VCEew5ZPS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JcYLG/btrnByBbP3s/Uooo1Ko7MnS4VCEew5ZPS1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JcYLG/btrnByBbP3s/Uooo1Ko7MnS4VCEew5ZPS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJcYLG%2FbtrnByBbP3s%2FUooo1Ko7MnS4VCEew5ZPS1%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;280&quot; height=&quot;196&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;511&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. Betty Wilma 입력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;Parent&amp;gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 30%; height: 80px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Key&lt;/td&gt;
&lt;td&gt;Value&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fred&lt;/td&gt;
&lt;td&gt;Fred&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Barney&lt;/td&gt;
&lt;td&gt;Fred&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Betty&lt;/td&gt;
&lt;td&gt;Fred&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wilma&lt;/td&gt;
&lt;td&gt;Fred&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;setSize&amp;gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 34.4757%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.7376%;&quot;&gt;Key&lt;/td&gt;
&lt;td style=&quot;width: 13.6093%;&quot;&gt;Value&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.7376%;&quot;&gt;Fred&lt;/td&gt;
&lt;td style=&quot;width: 13.6093%;&quot;&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.7376%;&quot;&gt;Barney&lt;/td&gt;
&lt;td style=&quot;width: 13.6093%;&quot;&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.7376%;&quot;&gt;Betty&lt;/td&gt;
&lt;td style=&quot;width: 13.6093%;&quot;&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.7376%;&quot;&gt;Wilma&lt;/td&gt;
&lt;td style=&quot;width: 13.6093%;&quot;&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;Tree&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;745&quot; data-origin-height=&quot;520&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ruAGp/btrnE98izW7/ZluXvkGgB5q1OuBvNKJM51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ruAGp/btrnE98izW7/ZluXvkGgB5q1OuBvNKJM51/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ruAGp/btrnE98izW7/ZluXvkGgB5q1OuBvNKJM51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FruAGp%2FbtrnE98izW7%2FZluXvkGgB5q1OuBvNKJM51%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;266&quot; height=&quot;520&quot; data-origin-width=&quot;745&quot; data-origin-height=&quot;520&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1639286091003&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Answer:
2
3
4&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;두 번째 Test Case&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. Fred Barney 입력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;Parent&amp;gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 25.8545%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 7.15424%;&quot;&gt;Key&lt;/td&gt;
&lt;td style=&quot;width: 11.3441%;&quot;&gt;Value&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 7.15424%;&quot;&gt;Fred&lt;/td&gt;
&lt;td style=&quot;width: 11.3441%;&quot;&gt;Fred&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 7.15424%;&quot;&gt;Barney&lt;/td&gt;
&lt;td style=&quot;width: 11.3441%;&quot;&gt;Fred&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;setSize&amp;gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 26.5117%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 8.98614%;&quot;&gt;Key&lt;/td&gt;
&lt;td style=&quot;width: 14.9497%;&quot;&gt;Value&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 8.98614%;&quot;&gt;Fred&lt;/td&gt;
&lt;td style=&quot;width: 14.9497%;&quot;&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 8.98614%;&quot;&gt;Barney&lt;/td&gt;
&lt;td style=&quot;width: 14.9497%;&quot;&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;Tree&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;474&quot; data-origin-height=&quot;511&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dusi8H/btrnHTcN6Fx/Z3EFTpmflqVk5gb5fWFb5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dusi8H/btrnHTcN6Fx/Z3EFTpmflqVk5gb5fWFb5k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dusi8H/btrnHTcN6Fx/Z3EFTpmflqVk5gb5fWFb5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdusi8H%2FbtrnHTcN6Fx%2FZ3EFTpmflqVk5gb5fWFb5k%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;210&quot; height=&quot;511&quot; data-origin-width=&quot;474&quot; data-origin-height=&quot;511&quot;/&gt;&lt;/span&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;size18&quot;&gt;2. Betty Wilma 입력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;Parent&amp;gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 30.3488%; height: 60px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 16.1628%; height: 20px;&quot;&gt;Key&lt;/td&gt;
&lt;td style=&quot;width: 14.0697%; height: 20px;&quot;&gt;Value&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 16.1628%; height: 20px;&quot;&gt;Fred&lt;/td&gt;
&lt;td style=&quot;width: 14.0697%; height: 20px;&quot;&gt;Fred&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 16.1628%; height: 20px;&quot;&gt;Barney&lt;/td&gt;
&lt;td style=&quot;width: 14.0697%; height: 20px;&quot;&gt;Fred&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.1628%;&quot;&gt;Betty&lt;/td&gt;
&lt;td style=&quot;width: 14.0697%;&quot;&gt;Betty&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.1628%;&quot;&gt;Wilma&lt;/td&gt;
&lt;td style=&quot;width: 14.0697%;&quot;&gt;Betty&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;setSize&amp;gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 30.814%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.6977%;&quot;&gt;Key&lt;/td&gt;
&lt;td style=&quot;width: 15%;&quot;&gt;Value&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.6977%;&quot;&gt;Fred&lt;/td&gt;
&lt;td style=&quot;width: 15%;&quot;&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.6977%;&quot;&gt;Barney&lt;/td&gt;
&lt;td style=&quot;width: 15%;&quot;&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.6977%;&quot;&gt;Betty&lt;/td&gt;
&lt;td style=&quot;width: 15%;&quot;&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.6977%;&quot;&gt;Wilma&lt;/td&gt;
&lt;td style=&quot;width: 15%;&quot;&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;Tree&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;480&quot; data-origin-height=&quot;518&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bd50B9/btrnB83y9kL/To3bclkks1tLnMDINrMyk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bd50B9/btrnB83y9kL/To3bclkks1tLnMDINrMyk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bd50B9/btrnB83y9kL/To3bclkks1tLnMDINrMyk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbd50B9%2FbtrnB83y9kL%2FTo3bclkks1tLnMDINrMyk0%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;208&quot; height=&quot;225&quot; data-origin-width=&quot;480&quot; data-origin-height=&quot;518&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. Barney Betty 입력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;Parent&amp;gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 36.0465%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.8605%;&quot;&gt;Key&lt;/td&gt;
&lt;td style=&quot;width: 19.0698%;&quot;&gt;Value&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.8605%;&quot;&gt;Fred&lt;/td&gt;
&lt;td style=&quot;width: 19.0698%;&quot;&gt;Fred&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.8605%;&quot;&gt;Barney&lt;/td&gt;
&lt;td style=&quot;width: 19.0698%;&quot;&gt;Fred&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.8605%;&quot;&gt;Betty&lt;/td&gt;
&lt;td style=&quot;width: 19.0698%;&quot;&gt;Fred&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.8605%;&quot;&gt;Wilma&lt;/td&gt;
&lt;td style=&quot;width: 19.0698%;&quot;&gt;Fred&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;setSize&amp;gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 36.0465%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 17.3256%;&quot;&gt;Key&lt;/td&gt;
&lt;td style=&quot;width: 18.6046%;&quot;&gt;Value&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 17.3256%;&quot;&gt;Fred&lt;/td&gt;
&lt;td style=&quot;width: 18.6046%;&quot;&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 17.3256%;&quot;&gt;Barney&lt;/td&gt;
&lt;td style=&quot;width: 18.6046%;&quot;&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 17.3256%;&quot;&gt;Betty&lt;/td&gt;
&lt;td style=&quot;width: 18.6046%;&quot;&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 17.3256%;&quot;&gt;Wilma&lt;/td&gt;
&lt;td style=&quot;width: 18.6046%;&quot;&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;Tree&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;745&quot; data-origin-height=&quot;520&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ruAGp/btrnE98izW7/ZluXvkGgB5q1OuBvNKJM51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ruAGp/btrnE98izW7/ZluXvkGgB5q1OuBvNKJM51/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ruAGp/btrnE98izW7/ZluXvkGgB5q1OuBvNKJM51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FruAGp%2FbtrnE98izW7%2FZluXvkGgB5q1OuBvNKJM51%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;266&quot; height=&quot;520&quot; data-origin-width=&quot;745&quot; data-origin-height=&quot;520&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1639286706362&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Answer:
2
2
4&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1639284446574&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package unionfind;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.StringTokenizer;

public class BOJ4195 {

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        int T = Integer.parseInt(br.readLine());
        for(int i = 0; i &amp;lt; T; i++){
            solution(br, bw);
        }
        bw.flush();
    }

    public static HashMap&amp;lt;String, String&amp;gt; parent;
    public static HashMap&amp;lt;String, Integer&amp;gt; setSize;
    private static void solution(BufferedReader br, BufferedWriter bw) throws Exception {
        int N = Integer.parseInt(br.readLine());
        parent = new HashMap&amp;lt;String, String&amp;gt;(); // 루트 노드 정보
        setSize = new HashMap&amp;lt;String, Integer&amp;gt;(); // 집합의 사이즈

        StringTokenizer st = null;
        for(int i = 0; i &amp;lt; N; i++){
            st = new StringTokenizer(br.readLine());
            String a = st.nextToken();
            String b = st.nextToken();

            // 입력 받을 때 초기화
            if(!setSize.containsKey(a)) setSize.put(a, 1);
            if(!setSize.containsKey(b)) setSize.put(b, 1);
            if(!parent.containsKey(a)) parent.put(a, a);
            if(!parent.containsKey(b)) parent.put(b, b);

            if(find(a) != find(b)){
                union(a, b);
            }
            // a, b 친구 관계를 맺었으므로 한 명의 루트 노드에 대한 사이즈만 출력하면 됨
            bw.write(setSize.get(find(a)) + &quot;\n&quot;);
        }
    }

    private static void union(String a, String b){
        a = find(a);
        b = find(b);

        if(setSize.get(a) &amp;gt;= setSize.get(b)){
            parent.put(b, a);
            setSize.put(a, setSize.get(a) + setSize.get(b));
            setSize.put(b, 0);
        } else {
            parent.put(a, b);
            setSize.put(b, setSize.get(b) + setSize.get(a));
            setSize.put(a, 0);
        }
    }

    private static String find(String a){
        if(parent.get(a) == a) return a;
        parent.put(a, find(parent.get(a)));
        return parent.get(a);
    }

}&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Problem Solving/BOJ</category>
      <category>union-find</category>
      <author>gom20</author>
      <guid isPermaLink="true">https://gom20.tistory.com/218</guid>
      <comments>https://gom20.tistory.com/218#entry218comment</comments>
      <pubDate>Sun, 12 Dec 2021 14:31:35 +0900</pubDate>
    </item>
  </channel>
</rss>