<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>이름짓기어려워</title>
    <link>https://chosh95.tistory.com/</link>
    <description>이것 저것 공부 기록을 위한 컴퓨터 공학생의 블로그</description>
    <language>ko</language>
    <pubDate>Sun, 5 Jul 2026 13:10:45 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>cho____sh</managingEditor>
    <image>
      <title>이름짓기어려워</title>
      <url>https://tistory1.daumcdn.net/tistory/3537923/attach/cbde42c1819845119da2fe660b22dd1b</url>
      <link>https://chosh95.tistory.com</link>
    </image>
    <item>
      <title>[git] 커밋 합치기</title>
      <link>https://chosh95.tistory.com/508</link>
      <description>&lt;p&gt;기록용&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;커밋, 푸시를 여러번해서 git log가 지저분해졌을 때 합칠 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;git rebase -i HEAD~3 // 가장 최근 커밋포함 3개의 커밋을 합친다.&lt;/p&gt;
&lt;p&gt;위 명령어 입력시 3개의 커밋 이력이 나오는데,&amp;nbsp;&lt;/p&gt;
&lt;p&gt;제일 위의 커밋 제외하고 나머지를 pick에서 squash로 입력한 후 :wq로 나온다.&lt;/p&gt;
&lt;p&gt;그 후 커밋 메세지를 원하는대로 수정한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그후 push하면 된다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;git push origin &amp;lt;branch이름&amp;gt; -f&amp;nbsp;&lt;/p&gt;
&lt;p&gt;명령어를 통해 강제로 push 해주면 여러개의 커밋이 하나로 합쳐지는 것을 볼 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;git branch &amp;lt;branch이름&amp;gt;&lt;/p&gt;
&lt;p&gt;으로 브랜치 생성&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;git checkout &amp;lt;branch이름&amp;gt;&lt;/p&gt;
&lt;p&gt;으로 브랜치 이동&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;master로 이동 후 git merge &amp;lt;branch이름&amp;gt; 을 입력하면 master에 branch 내용을 합치게 된다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍 이론 &amp;amp; 책/기타</category>
      <author>cho____sh</author>
      <guid isPermaLink="true">https://chosh95.tistory.com/508</guid>
      <comments>https://chosh95.tistory.com/508#entry508comment</comments>
      <pubDate>Wed, 16 Dec 2020 18:30:58 +0900</pubDate>
    </item>
    <item>
      <title>[백준] 로마 카톨릭 미사 (9518번)</title>
      <link>https://chosh95.tistory.com/506</link>
      <description>&lt;h2&gt;문제&lt;/h2&gt;
&lt;p&gt;로마 카톨릭 미사에서 가장 멋진 부분은 사람들이 서로 악수를 하면서 &quot;평화가 함께하기를&quot; 이라고 말하는 평화 의식이다.&lt;/p&gt;
&lt;p&gt;성당에는 R개의 벤치가 한 행에 하나씩 있고, 각 벤치에는 총 S명이 앉을 수 있다. 성당의 좌석 배치는 크기가 R &amp;times; S인 행렬로 나타낼 수 있고, 행렬의 각 원소는 사람이 있는지 없는지로 나타낼 수 있다. 모든 사람은 자신의 이웃과 악수를 한다고 가정한다. 이웃은 사람이 있는 칸과 인접한 칸 여덟개이다. (칸이 존재하지 않을 수도 있다)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUyjd9/btqLYL3qykv/UxKZWXYE929KPq2kIkD1W1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUyjd9/btqLYL3qykv/UxKZWXYE929KPq2kIkD1W1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUyjd9/btqLYL3qykv/UxKZWXYE929KPq2kIkD1W1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUyjd9%2FbtqLYL3qykv%2FUxKZWXYE929KPq2kIkD1W1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;상근이는 오늘도 늦잠을 자 미사에 늦었고, 가장 좋아하는 평화 의식 시간을 참여하기 위해 성당 입구까지 달려왔다. 상근이는 최대한 많은 사람과 악수를 할 수 있는 자리에 앉으려고 한다. 만약, 남은 자리가 없는 경우에는 상근이는 저녁 미사에 다시 참가하려고 한다. 또, 상근이보다 지각하는 사람은 없다.&lt;/p&gt;
&lt;p&gt;상근이가 들어가기 바로 전 성당에 앉아있는 사람의 배치가 주어진다. 평화 의식이 진행되는 동안 총 몇 번의 악수가 행해지는지 구하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;h2&gt;입력&lt;/h2&gt;
&lt;p&gt;첫째 줄에 R과 S가 주어진다. (1 &amp;le; R, S &amp;le; 50)&lt;/p&gt;
&lt;p&gt;다음 R개 줄에는 S개의 문자가 주어진다. 이 R &amp;times; S 개의 문자는 성당에 자리 배치를 나타낸다. '.'은 빈 자리, 'o'는 사람이 앉아있는 자리이다.&lt;/p&gt;
&lt;h2&gt;출력&lt;/h2&gt;
&lt;p&gt;평화 의식에서 총 몇 번의 악수가 행해지는지 출력한다.&lt;/p&gt;
&lt;h2&gt;예제 입력 1&lt;span&gt;&amp;nbsp;&lt;/span&gt;복사&lt;/h2&gt;
&lt;p&gt;2 3 ..o o..&lt;/p&gt;
&lt;h2&gt;예제 출력 1&lt;span&gt;&amp;nbsp;&lt;/span&gt;복사&lt;/h2&gt;
&lt;p&gt;2&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;문제 설명과 예제가 애매해서 실수할 여지가 있는 문제다.&lt;/p&gt;
&lt;p&gt;문제는 상근이가 추가되었을 때의 악수 횟수가 아닌, 상근이를 포함해서 총 몇번의 악수가 이루어지는지를 묻고 있다.&lt;/p&gt;
&lt;p&gt;따라서 브루트포스로 상근이를 모든 빈 좌석에 앉혀서 총 몇번의 악수가 이뤄지는지를 계산해야 한다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그런데 상근이를 어디에 앉히던, 기존에 있던 사람들끼리의 악수 횟수는 변하지 않기 때문에, 기존의 사람들의 총 악수횟수를 구한 후, 상근이의 최대 악수 횟수를 더하면 답을 구할 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;기존 사람들의 악수 횟수는 bfs를 이용해서 계산했다. 주의할점은 2차원 배열로 악수 여부를 기록하지 말고, 4차원 배열로 (x1,y1) - (x2,y2)의 악수 여부를 기록해야 한다. 나는 visit[][] 2차원 배열로 큐에 넣어서 조사했는지를 기록하고,&amp;nbsp;&lt;/p&gt;
&lt;p&gt;hand[][][][] 4차원 배열로 두 사람의 악수 여부를 기록했다. 이런 방식으로 모든 사람의 악수 여부를 기록한 후, 각 빈자리에 상근이를 앉히며, 8가지 주위 방향에 사람이 몇 명 있는지를 계산하면 최대 악수 횟수를 구할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;코드 원본 : &lt;a href=&quot;https://github.com/chosh95/STUDY/blob/master/BaekJoon/2020/%EB%A1%9C%EB%A7%88%20%EC%B9%B4%ED%86%A8%EB%A6%AD%20%EB%AF%B8%EC%82%AC%20(9518%EB%B2%88).cpp&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/chosh95/STUDY/blob/master/BaekJoon/2020/%EB%A1%9C%EB%A7%88%20%EC%B9%B4%ED%86%A8%EB%A6%AD%20%EB%AF%B8%EC%82%AC%20(9518%EB%B2%88).cpp&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1603797100720&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;object&quot; data-og-title=&quot;chosh95/STUDY&quot; data-og-description=&quot;프로그래밍 문제 및 알고리즘 정리. Contribute to chosh95/STUDY development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/chosh95/STUDY/blob/master/BaekJoon/2020/%EB%A1%9C%EB%A7%88%20%EC%B9%B4%ED%86%A8%EB%A6%AD%20%EB%AF%B8%EC%82%AC%20(9518%EB%B2%88).cpp&quot; data-og-url=&quot;https://github.com/chosh95/STUDY&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/eIJKA/hyH12NcoTa/uvow7rGA39KqNNvYlyQJyk/img.jpg?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://github.com/chosh95/STUDY/blob/master/BaekJoon/2020/%EB%A1%9C%EB%A7%88%20%EC%B9%B4%ED%86%A8%EB%A6%AD%20%EB%AF%B8%EC%82%AC%20(9518%EB%B2%88).cpp&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/chosh95/STUDY/blob/master/BaekJoon/2020/%EB%A1%9C%EB%A7%88%20%EC%B9%B4%ED%86%A8%EB%A6%AD%20%EB%AF%B8%EC%82%AC%20(9518%EB%B2%88).cpp&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/eIJKA/hyH12NcoTa/uvow7rGA39KqNNvYlyQJyk/img.jpg?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;chosh95/STUDY&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;프로그래밍 문제 및 알고리즘 정리. Contribute to chosh95/STUDY development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;C++ 코드&lt;/p&gt;
&lt;pre id=&quot;code_1603797105469&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;algorithm&amp;gt;
#include &amp;lt;queue&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;string&amp;gt;
using namespace std;

int R, S, res;
int hand[51][51][51][51]; // (a,b) - (x,y)의 악수 여부 기록
int visit[51][51]; // (a,b)를 조사했는가. 조사 여부와 악수 여부는 다르다.
int p[51][51]; // 좌석 기록
int dx[8] = { -1,0,1,1,1,0,-1,-1 }; // 8가지 방향
int dy[8] = { 1,1,1,0,-1,-1,-1,0 };

void bfs(int a, int b)
{
	queue&amp;lt;pair&amp;lt;int, int&amp;gt;&amp;gt; q;
	q.push({ a,b });
	visit[a][b] = 1;

	while (!q.empty()) {
		int x = q.front().first;
		int y = q.front().second;
		q.pop();
		visit[x][y] = 1; 

		for (int i = 0; i &amp;lt; 8; i++) {
			int nx = x + dx[i];
			int ny = y + dy[i];
			if (nx &amp;lt; 1 || ny&amp;lt; 1 || nx &amp;gt; R || ny &amp;gt; S) continue;
			if (p[nx][ny] == 0) continue; //빈 좌석이면 건너뜀
			if (hand[x][y][nx][ny] == 1) continue; //악수 했으면 건너뜀
			q.push({ nx,ny });
			hand[x][y][nx][ny] = hand[nx][ny][x][y] = 1;
			res++; //악수 횟수 추가
		}
	}
}

int main()
{
	cin &amp;gt;&amp;gt; R &amp;gt;&amp;gt; S;
	string str;
	for (int i = 1; i &amp;lt;= R; i++) {
		cin &amp;gt;&amp;gt; str;
		for (int j = 1; j &amp;lt;= S; j++) {
			if (str[j - 1] == '.') p[i][j] = 0;
			else p[i][j] = 1;
		}
	}

	for (int i = 1; i &amp;lt;= R; i++) 
		for (int j = 1; j &amp;lt;= S; j++) 
			if (visit[i][j] == 0 &amp;amp;&amp;amp; p[i][j] == 1) 
				bfs(i, j); // (i, j) 조사. 상근이 없이 최대 몇 번 악수하는지 조사

	int maxNum = 0; // 상근이가 악수할 최대 회수 기록
	for (int i = 1; i &amp;lt;= R; i++) {
		for (int j = 1; j &amp;lt;= S; j++) {
			if (p[i][j] == 1) continue; // 빈좌석만 앉아야 한다.
			int cur = 0;
			for (int k = 0; k &amp;lt; 8; k++) {
				int nx = i + dx[k];
				int ny = j + dy[k];
				if (nx&amp;lt;1 || ny&amp;lt;1 || nx&amp;gt;R || ny&amp;gt;S) continue;
				if (p[nx][ny] == 1) cur++; // 악수 회수 추가
			}
			maxNum = max(maxNum, cur);
		}
	}

	cout &amp;lt;&amp;lt; res + maxNum; // 상근이 없이 악수하는 횟수 + 상근이가 추가 됐을 때 추가 악수 횟수
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/백준</category>
      <author>cho____sh</author>
      <guid isPermaLink="true">https://chosh95.tistory.com/506</guid>
      <comments>https://chosh95.tistory.com/506#entry506comment</comments>
      <pubDate>Tue, 27 Oct 2020 20:17:03 +0900</pubDate>
    </item>
    <item>
      <title>[백준] 소풍 (2026번)</title>
      <link>https://chosh95.tistory.com/505</link>
      <description>&lt;h2&gt;문제&lt;/h2&gt;
&lt;p&gt;원장선생님께서는 1부터 N까지 번호가 붙은 N(K &amp;le; N &amp;le; 900)명의 학생들 중에서 K(1 &amp;le; K &amp;le; 62)명의 학생들을 소풍에 보내려고 한다. 그런데 원장선생님께서는 중간에 싸움이 일어나면 안되므로 소풍을 갈 학생들이 모두 서로 친구 사이이기를 원한다. 원장선생님께서는 이러한 일을 이번에 조교로 참가한 고은이에게 친구 관계에 대한 정보를 F(1 &amp;le; F &amp;le; 5,600)개를 주시며 K명을 선발하라고 부탁하였다.&lt;/p&gt;
&lt;p&gt;고은 조교를 도와 소풍을 가게 될 K명의 학생들을 결정하시오.&lt;/p&gt;
&lt;h2&gt;입력&lt;/h2&gt;
&lt;p&gt;첫째 줄에 공백으로 분리된 세 정수 K, N, F가 주어진다. 다음 F개의 줄에는 서로 친구 관계인 두 사람의 번호가 주어진다. 친구 관계는 상호적인 관계이므로 2번 학생이 4번 학생을 좋아하면 4번 학생도 2번 학생을 좋아한다. 같은 친구 관계가 여러 번 주어지는 경우는 없다.&lt;/p&gt;
&lt;h2&gt;출력&lt;/h2&gt;
&lt;p&gt;만약 K명의 친구 관계인 학생들이 존재하지 않는다면 -1을 출력한다. 그 외의 경우에는, K개의 줄에 학생들의 번호를 증가하는 순서로 한 줄에 한 개씩 출력한다. 여러 경우가 존재한다면 첫 번째 학생의 번호가 제일 작은 것을 출력한다. 첫 번째 학생의 번호가 같은 경우라면, 두 번째 학생의 번호가 작은 경우를 출력하고, 이와 같은 식으로 출력한다.&lt;/p&gt;
&lt;h2&gt;예제 입력 1&lt;span&gt;&amp;nbsp;&lt;/span&gt;복사&lt;/h2&gt;
&lt;p&gt;4 6 8 1 2 1 3 1 6 2 3 2 6 3 6 4 5 5 6&lt;/p&gt;
&lt;h2&gt;예제 출력 1&lt;span&gt;&amp;nbsp;&lt;/span&gt;복사&lt;/h2&gt;
&lt;p&gt;1 2 3 6&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;K명의 서로 친구인 학생을 골라야 하는 백트래킹 문제이다.&lt;/p&gt;
&lt;p&gt;처음엔 K명이 서로 연결되어 있으면 되는 줄 알고 풀었다가 틀렸습니다가 떴다.&lt;/p&gt;
&lt;p&gt;1 - 2 - 3 - 6 이렇게 친구로 연결되면 되는 게 아니라, 1 - 2 - 3 - 6 이면서 1 - 3, 1 - 6,&amp;nbsp; 2 - 6까지 모두 친구 관계여야 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;해결 방법은 한 명씩 백트래킹으로 조사하는 것이다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;1번 학생부터 가능한 모든 관계를 조사해야 한다.&lt;/p&gt;
&lt;p&gt;새로운 친구를 늘릴 땐 현재까지 친구인 학생들과도 모두 친구인지를 조사해야 한다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;모든 학생과 친구라면 새로 친구를 늘리고, 그렇게 친구를 한 명씩 늘리면서 K명이 되면 결과 벡터에 친구들을 모두 기록하고 return 한다. 인덱스를 idx+1 부터 N까지 차례대로 증가시키기 때문에 결과 벡터는 항상 정렬된 상태로 저장된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;코드 원본 : &lt;a href=&quot;https://github.com/chosh95/STUDY/blob/master/BaekJoon/2020/%EC%86%8C%ED%92%8D%20(2026%EB%B2%88).cpp&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/chosh95/STUDY/blob/master/BaekJoon/2020/%EC%86%8C%ED%92%8D%20(2026%EB%B2%88).cpp&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1603774604929&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;object&quot; data-og-title=&quot;chosh95/STUDY&quot; data-og-description=&quot;프로그래밍 문제 및 알고리즘 정리. Contribute to chosh95/STUDY development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/chosh95/STUDY/blob/master/BaekJoon/2020/%EC%86%8C%ED%92%8D%20(2026%EB%B2%88).cpp&quot; data-og-url=&quot;https://github.com/chosh95/STUDY&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/25b4A/hyH0ZqyJG5/5Rov395AAcVMre8f31Woq1/img.jpg?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://github.com/chosh95/STUDY/blob/master/BaekJoon/2020/%EC%86%8C%ED%92%8D%20(2026%EB%B2%88).cpp&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/chosh95/STUDY/blob/master/BaekJoon/2020/%EC%86%8C%ED%92%8D%20(2026%EB%B2%88).cpp&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/25b4A/hyH0ZqyJG5/5Rov395AAcVMre8f31Woq1/img.jpg?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;chosh95/STUDY&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;프로그래밍 문제 및 알고리즘 정리. Contribute to chosh95/STUDY development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;C++ 코드&lt;/p&gt;
&lt;pre id=&quot;code_1603774610312&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;algorithm&amp;gt;
#include &amp;lt;vector&amp;gt;
using namespace std;
int K, N, F;
int p[901][901];
int visit[901];
vector&amp;lt;int&amp;gt; res;

void dfs(int idx, int cnt, vector&amp;lt;int&amp;gt; cur) {
	if (!res.empty()) return;
	if (cnt == K) {
		res = cur;
		return;
	}

	for (int i = idx + 1; i &amp;lt;= N; i++) {
		if (visit[i] == 1) continue;
		bool isFriend = true;
		for (int j = 0; j &amp;lt; cur.size(); j++) {
			if (p[cur[j]][i] == 0) {
				isFriend = false;
				break;
			}
		}
		if (isFriend) {
			visit[i] = 1;
			cur.push_back(i);
			dfs(i, cnt + 1, cur);
			cur.pop_back();
			visit[i] = 0;
		}
	}
}

int main()
{
	cin &amp;gt;&amp;gt; K &amp;gt;&amp;gt; N &amp;gt;&amp;gt; F;
	for (int a, b, i = 0; i &amp;lt; F; i++) {
		cin &amp;gt;&amp;gt; a &amp;gt;&amp;gt; b;
		p[a][b] = p[b][a] = 1;
	}

	for (int i = 1; i &amp;lt;= N; i++) {
		if (!res.empty()) break;
		visit[i] = 1;
		dfs(i, 1, { i });
		visit[i] = 0;
	}
	
	if (res.empty()) cout &amp;lt;&amp;lt; &quot;-1&quot;;
	else {
		for (int x : res)
			cout &amp;lt;&amp;lt; x &amp;lt;&amp;lt; &quot;\n&quot;;
	}
		
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/백준</category>
      <author>cho____sh</author>
      <guid isPermaLink="true">https://chosh95.tistory.com/505</guid>
      <comments>https://chosh95.tistory.com/505#entry505comment</comments>
      <pubDate>Tue, 27 Oct 2020 14:01:17 +0900</pubDate>
    </item>
    <item>
      <title>트리에서의 dp (백준 : 사회망 서비스(SNS) (2533번))</title>
      <link>https://chosh95.tistory.com/504</link>
      <description>&lt;h2&gt;문제&lt;/h2&gt;
&lt;p&gt;페이스북, 트위터, 카카오톡과 같은 사회망 서비스(SNS)가 널리 사용됨에 따라, 사회망을 통하여 사람들이 어떻게 새로운 아이디어를 받아들이게 되는가를 이해하는 문제가 중요해졌다. 사회망에서 사람들의 친구 관계는 그래프로 표현할 수 있는데, &amp;nbsp;이 그래프에서 사람은 정점으로 표현되고, 두 정점을 잇는 에지는 두 정점으로 표현되는 두 사람이 서로 친구 관계임을 표현한다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;예를 들어, 철수와 영희, 철수와 만수, 영희와 순희가 서로 친구 관계라면 이를 표현하는 친구 관계 그래프는 다음과 같다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Sx08R/btqLwLwUh85/YV9dEEGIQY7nbtxIytuHf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Sx08R/btqLwLwUh85/YV9dEEGIQY7nbtxIytuHf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Sx08R/btqLwLwUh85/YV9dEEGIQY7nbtxIytuHf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSx08R%2FbtqLwLwUh85%2FYV9dEEGIQY7nbtxIytuHf0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;친구 관계 그래프를 이용하면 사회망 서비스에서 어떤 새로운 아이디어가 전파되는 과정을 이해하는데 도움을 줄 수 있다. 어떤 새로운 아이디어를 먼저 받아들인 사람을 얼리 아답터(early adaptor)라고 하는데, 사회망 서비스에 속한 사람들은 얼리 아답터이거나 얼리 아답터가 아니다. 얼리 아답터가 아닌 사람들은 자신의 모든 친구들이 얼리 아답터일 때만 이 아이디어를 받아들인다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;어떤 아이디어를 사회망 서비스에서 퍼뜨리고자 할 때, 가능한 한 최소의 수의 얼리 아답터를 확보하여 모든 사람이 이 아이디어를 받아들이게 하는 &amp;nbsp;문제는 매우 중요하다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;일반적인 그래프에서 이 문제를 푸는 것이 매우 어렵다는 것이 알려져 있기 때문에, 친구 관계 그래프가 트리인 경우, 즉 모든 두 정점 사이에 이들을 잇는 경로가 존재하면서 사이클이 존재하지 않는 경우만 고려한다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;예를 들어, 8명의 사람으로 이루어진 다음 친구 관계 트리를 생각해보자. 2, 3, 4번 노드가 표현하는 사람들이 얼리 아답터라면, 얼리 아답터가 아닌 사람들은 자신의 모든 친구가 얼리 아답터이기 때문에 새로운 아이디어를 받아들인다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rEkP1/btqLuB9Q80i/zFnF0SxXLI54HXXCerJSnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rEkP1/btqLuB9Q80i/zFnF0SxXLI54HXXCerJSnK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rEkP1/btqLuB9Q80i/zFnF0SxXLI54HXXCerJSnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrEkP1%2FbtqLuB9Q80i%2FzFnF0SxXLI54HXXCerJSnK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;친구 관계 트리가 주어졌을 때, 모든 개인이 새로운 아이디어를 수용하기 위하여 필요한 최소 얼리 어답터의 수를 구하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;h2&gt;입력&lt;/h2&gt;
&lt;p&gt;첫 번째 줄에는 친구 관계 트리의 정점 개수 N이 주어진다. 단, 2 &amp;lt;= N &amp;lt;= 1,000,000이며, 각 정점은 1부터 N까지 일련번호로 표현된다. 두 번째 줄부터 N-1개의 줄에는 각 줄마다 친구 관계 트리의 에지 (u, v)를 나타내는 두 정수 u 와 v가 하나의 빈칸을 사이에 두고 주어진다.&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;출력&lt;/h2&gt;
&lt;p&gt;주어진 친구 관계 그래프에서 아이디어를 전파하는데 필요한 얼리 아답터의 최소 수를 하나의 정수로 출력한다.&lt;/p&gt;
&lt;h2&gt;예제 입력 1&lt;span&gt;&amp;nbsp;&lt;/span&gt;복사&lt;/h2&gt;
&lt;p&gt;8 1 2 1 3 1 4 2 5 2 6 4 7 4 8&lt;/p&gt;
&lt;h2&gt;예제 출력 1&lt;span&gt;&amp;nbsp;&lt;/span&gt;복사&lt;/h2&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;트리에서 dynamic programming 으로 가장 많은 사람들이 푼 문제라서 이 문제를 설명하려 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;트리 dp 문제들을 풀기 위해서 우선 트리를 만들어야한다.&lt;/p&gt;
&lt;p&gt;반드시 트리를 만들 필요는 없고, 벡터를 이용한 인접 리스트처럼 부모 노드에서 자식 노드를 가리킬 수단만 있으면 된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;문제 요구사항에 맞게 우선, 양방향 그래프로 v라는 벡터에 값을 넣어준다.&lt;/p&gt;
&lt;p&gt;그 후 makeChild라는 함수로 1번 노드를 루트로 하는 자식 노드들을 기록한다.&lt;/p&gt;
&lt;p&gt;트리를 모두 만들었으면 문제를 풀 준비가 됐다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;보통 이런 유형은 dfs를 이용한 백트래킹을 한다.&lt;/p&gt;
&lt;p&gt;dp 배열의 정의를&lt;/p&gt;
&lt;p&gt;dp[i][0] : i번 노드를 루트로 하고 i번 노드가 얼리어답터가 아닐 때 필요한 최소 얼리어답터 수&lt;/p&gt;
&lt;p&gt;dp[i][1] : &lt;span style=&quot;color: #333333;&quot;&gt;i번 노드를 루트로 하고 i번 노드가 얼리어답터일 때 필요한 최소 얼리어답터 수&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;라고 하자.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;만약 i번 노드가 얼리어답터가 아니라면 그 자식들은 반드시 얼리어답터야 한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;i번 노드가 얼리어답터라면 그 자식들은 얼리어답터여도 되고 아니어도 된다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이 정의에 맞도록 구현하는 건 크게 어렵지 않다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;코드를 보고 이해하자.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;코드 원본 : &lt;a href=&quot;https://github.com/chosh95/STUDY/blob/master/BaekJoon/2020/%EC%82%AC%ED%9A%8C%EB%A7%9D%20%EC%84%9C%EB%B9%84%EC%8A%A4(SNS)%20(2533%EB%B2%88).cpp&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/chosh95/STUDY/blob/master/BaekJoon/2020/%EC%82%AC%ED%9A%8C%EB%A7%9D%20%EC%84%9C%EB%B9%84%EC%8A%A4(SNS)%20(2533%EB%B2%88).cpp&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1603347316897&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;object&quot; data-og-title=&quot;chosh95/STUDY&quot; data-og-description=&quot;프로그래밍 문제 및 알고리즘 정리. Contribute to chosh95/STUDY development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/chosh95/STUDY/blob/master/BaekJoon/2020/%EC%82%AC%ED%9A%8C%EB%A7%9D%20%EC%84%9C%EB%B9%84%EC%8A%A4(SNS)%20(2533%EB%B2%88).cpp&quot; data-og-url=&quot;https://github.com/chosh95/STUDY&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dCpf6G/hyHXj3EPS2/rrdiJ12zGC0sFiBUae4MlK/img.jpg?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://github.com/chosh95/STUDY/blob/master/BaekJoon/2020/%EC%82%AC%ED%9A%8C%EB%A7%9D%20%EC%84%9C%EB%B9%84%EC%8A%A4(SNS)%20(2533%EB%B2%88).cpp&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/chosh95/STUDY/blob/master/BaekJoon/2020/%EC%82%AC%ED%9A%8C%EB%A7%9D%20%EC%84%9C%EB%B9%84%EC%8A%A4(SNS)%20(2533%EB%B2%88).cpp&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dCpf6G/hyHXj3EPS2/rrdiJ12zGC0sFiBUae4MlK/img.jpg?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;chosh95/STUDY&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;프로그래밍 문제 및 알고리즘 정리. Contribute to chosh95/STUDY development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;pre id=&quot;code_1603347320774&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;algorithm&amp;gt;
#include &amp;lt;vector&amp;gt;
using namespace std;
int N;
vector&amp;lt;int&amp;gt; v[1000001];
vector&amp;lt;int&amp;gt; child[1000001];
int visit[1000001];
int dp[1000001][2]; // dp[i][0] : i가 얼리어답터일 때, dp[i][1] : 얼리어답터 아닐 때

void makeChild(int cur) {
	for (auto next : v[cur]) {
		if (visit[next] == 0) {
			visit[next] = 1;
			child[cur].push_back(next);
			makeChild(next);
		}
	}
}

int dfs(int cur, int state) {
	
	if (dp[cur][state] != 0) return dp[cur][state];

	if (state == 0) {
		for (int next : child[cur]) {
			dp[cur][state] += dfs(next, 1);
		}
	}
	else {
		for (int next : child[cur]) {
			dp[cur][state] += min(dfs(next,0), dfs(next, 1));
		}
		dp[cur][state]++; // cur 노드도 얼리어답터이므로 1 추가
	}

	return dp[cur][state];
}

int main()
{
	cin &amp;gt;&amp;gt; N;
	for (int u, w, i = 1; i &amp;lt; N; i++) {
		cin &amp;gt;&amp;gt; u &amp;gt;&amp;gt; w;
		v[u].push_back(w);
		v[w].push_back(u);
	}

	visit[1] = 1;
	makeChild(1);

	cout &amp;lt;&amp;lt; min(dfs(1, 0), dfs(1, 1));
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/기본 알고리즘</category>
      <author>cho____sh</author>
      <guid isPermaLink="true">https://chosh95.tistory.com/504</guid>
      <comments>https://chosh95.tistory.com/504#entry504comment</comments>
      <pubDate>Thu, 22 Oct 2020 15:24:50 +0900</pubDate>
    </item>
    <item>
      <title>[Songstagram] List - &amp;gt; Set으로 Entity Type 변경</title>
      <link>https://chosh95.tistory.com/502</link>
      <description>&lt;p&gt;그동안 일대다 관계에서 '다'를 표현할 Entity의 Colletion으로 List를 사용했었다. 이전에 들었던 Spring 강의에서 List를 사용했기 때문이고, 문제가 없어 보였다. 그러나, 굳이 List가 아니라 Set으로도 표현이 가능함을 알게 되었고, 어떤 자료형이 더 최적 일지 고민했다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;알다시피 List는 중복이 허용되는 순서를 유지하는 자료를 모으는 자료형이고, Set은 중복이 허용되지 않는 순서가 없는 자료형이다. 혼자 고민하기보다, StackOverflow에 검색을 했더니 아래와 같은 좋은 글을 발견했다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/4655392/which-java-type-do-you-use-for-jpa-collections-and-why&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;stackoverflow.com/questions/4655392/which-java-type-do-you-use-for-jpa-collections-and-why&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1602497429923&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Which Java Type do you use for JPA collections and why?&quot; data-og-description=&quot;Which of the following collection types do you use in your JPA domain model and why: java.util.Collection java.util.List java.util.Set I was wondering whether there are some ground rules for this.&quot; data-og-host=&quot;stackoverflow.com&quot; data-og-source-url=&quot;https://stackoverflow.com/questions/4655392/which-java-type-do-you-use-for-jpa-collections-and-why&quot; data-og-url=&quot;https://stackoverflow.com/questions/4655392/which-java-type-do-you-use-for-jpa-collections-and-why&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bOmMNF/hyHQbkcQln/bTXMlO15aK1frHhQnzcsMk/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/4655392/which-java-type-do-you-use-for-jpa-collections-and-why&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://stackoverflow.com/questions/4655392/which-java-type-do-you-use-for-jpa-collections-and-why&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bOmMNF/hyHQbkcQln/bTXMlO15aK1frHhQnzcsMk/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;Which Java Type do you use for JPA collections and why?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;Which of the following collection types do you use in your JPA domain model and why: java.util.Collection java.util.List java.util.Set I was wondering whether there are some ground rules for this.&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;stackoverflow.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;JPA에서 Hibernate를 구현체로 사용할 때, List 자료형은 Bag이라는 자료형으로 변환이 된다고 한다. 이 Bag에는 치명적인 단점이 있다. 예를들어 userA가 작성한 글 제목이 &quot;ABC&quot;라는 글을 삭제하려 할 때,&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;delete from userPost where userName = &quot;userA&quot;;&lt;/p&gt;
&lt;p&gt;insert into userPost(userName, postTitle) values(&quot;userA&quot;, &quot;ABA&quot;);&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;insert into userPost(userName, postTitle) values(&quot;userA&quot;, &quot;ABB&quot;);&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;insert into userPost(userName, postTitle) values(&quot;userA&quot;, &quot;ABD&quot;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이런식으로 작성자가 userA인 글을 모두 삭제한 후 ABC가 아닌 나머지 값을 다시 insert 하는 식으로 쿼리가 실행된다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Bag 자료형을 사용하면 delete &amp;amp; update 를 실행할 때 delete All &amp;amp; re-insert 방식으로 구현이 된다는 것이다. 이는 프로그램 성능에는 치명적일 수 있다. 이런 문제를 피하기 위해 Set 자료형을 사용하면 Hibernate가 Bag 자료형을 사용하지 않고 문제를 해결할 수 있다고 한다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;생각해보면 내 프로젝트에서, 중복 허용이나 개체 순서는 중요하지 않기 때문에 List 자료형을 전부 Set으로 변경 &amp;amp; 적용했다. 객체가 정렬될 필요도 없기 때문에 TreeSet이 아닌 HashSet으로 설정했다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>프로젝트/Songstagram</category>
      <author>cho____sh</author>
      <guid isPermaLink="true">https://chosh95.tistory.com/502</guid>
      <comments>https://chosh95.tistory.com/502#entry502comment</comments>
      <pubDate>Mon, 12 Oct 2020 19:26:02 +0900</pubDate>
    </item>
    <item>
      <title>[Songstagram] 쿼리 최적화</title>
      <link>https://chosh95.tistory.com/501</link>
      <description>&lt;p&gt;Posts라는 게시글 정보를 위한 엔티티와 Comments라는 댓글 엔티티가 1대다로 맵핑되어 있다.&lt;/p&gt;
&lt;p&gt;맵핑 정보는 아래 코드와 같다. Lazy로 로딩하기 때문에 posts 정보를 가져와도 comments 정보까지 가져오진 않는다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;749&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kG3D7/btqKtdAfleP/AdNcUbxG3Cjxi8JBJ0H2kK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kG3D7/btqKtdAfleP/AdNcUbxG3Cjxi8JBJ0H2kK/img.png&quot; data-alt=&quot;Posts의 멤버 변수 commentsList&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kG3D7/btqKtdAfleP/AdNcUbxG3Cjxi8JBJ0H2kK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkG3D7%2FbtqKtdAfleP%2FAdNcUbxG3Cjxi8JBJ0H2kK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;749&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;Posts의 멤버 변수 commentsList&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;310&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYomoa/btqKte6Zjmg/LbCx6BzUIJG1K64sMtVLo0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYomoa/btqKte6Zjmg/LbCx6BzUIJG1K64sMtVLo0/img.png&quot; data-alt=&quot;Comments의 멤버 변수 posts&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYomoa/btqKte6Zjmg/LbCx6BzUIJG1K64sMtVLo0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYomoa%2FbtqKte6Zjmg%2FLbCx6BzUIJG1K64sMtVLo0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;310&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;Comments의 멤버 변수 posts&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이 상황에서 댓글 정보를 가져올 때 posts.getCommentsList()를 통해 댓글을 가져오는 게 빠를까&lt;/p&gt;
&lt;p&gt;아니면 CommentsRepository에서 쿼리를 통해 posts 에 작성된 댓글을 가져오는 게 빠를까.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;궁금증을 해결하기 위해 직접 실행해봤다. 실험해볼 핵심 코드는 아래 두 줄이다.&lt;/p&gt;
&lt;p&gt;윗줄의 코드는 posts의 멤버 변수를 통해 댓글 목록을 가져오는 것이고, 아래 코드는 직접 쿼리를 날려서 가져오는 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tAfPl/btqKnqHUpLk/FVnqMnHfXhl6JqAfcSKsz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tAfPl/btqKnqHUpLk/FVnqMnHfXhl6JqAfcSKsz1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tAfPl/btqKnqHUpLk/FVnqMnHfXhl6JqAfcSKsz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtAfPl%2FbtqKnqHUpLk%2FFVnqMnHfXhl6JqAfcSKsz1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;언제 어느 쿼리가 날라가는지 보기 위해 아래와 같이 print 문을 삽입했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5nCW3/btqKkOpdW0C/EroGOGiWBp49zDzMjnj0E0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5nCW3/btqKkOpdW0C/EroGOGiWBp49zDzMjnj0E0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5nCW3/btqKkOpdW0C/EroGOGiWBp49zDzMjnj0E0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5nCW3%2FbtqKkOpdW0C%2FEroGOGiWBp49zDzMjnj0E0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;프로젝트를 실행한 후 동일한 게시글을 읽어서 어떻게 쿼리가 나오는 지 확인해봤다.&lt;/p&gt;
&lt;p&gt;아래 결과는 멤버변수를 통해 실행한 결과이다.&lt;/p&gt;
&lt;pre id=&quot;code_1602071708542&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;=============게시글 읽기 컨트롤러 시작=====================
Hibernate: 
    select
        posts0_.posts_id as posts_id1_4_0_,
        posts0_.create_date as create_d2_4_0_,
        posts0_.created_date as created_3_4_0_,
        posts0_.modified_date as modified4_4_0_,
        posts0_.content as content5_4_0_,
        posts0_.picture as picture6_4_0_,
        posts0_.singer as singer7_4_0_,
        posts0_.song_name as song_nam8_4_0_,
        posts0_.users_id as users_id9_4_0_ 
    from
        posts posts0_ 
    where
        posts0_.posts_id=?
Hibernate: 
    select
        users0_.users_id as users_id1_5_0_,
        users0_.email as email2_5_0_,
        users0_.name as name3_5_0_,
        users0_.password as password4_5_0_,
        users0_.picture as picture5_5_0_ 
    from
        users users0_ 
    where
        users0_.users_id=?
Hibernate: 
    select
        likes0_.likes_id as likes_id1_3_,
        likes0_.posts_id as posts_id2_3_,
        likes0_.users_id as users_id3_3_ 
    from
        likes likes0_ 
    where
        likes0_.posts_id=?
=========댓글 가져오기 시작========
=========댓글 가져오기 끝========
==============댓글 실제 사용=============
Hibernate: 
    select
        commentsli0_.posts_id as posts_id6_0_0_,
        commentsli0_.comments_id as comments1_0_0_,
        commentsli0_.comments_id as comments1_0_1_,
        commentsli0_.create_date as create_d2_0_1_,
        commentsli0_.created_date as created_3_0_1_,
        commentsli0_.modified_date as modified4_0_1_,
        commentsli0_.content as content5_0_1_,
        commentsli0_.posts_id as posts_id6_0_1_,
        commentsli0_.user_id as user_id7_0_1_ 
    from
        comments commentsli0_ 
    where
        commentsli0_.posts_id=?
Hibernate: 
    select
        users0_.users_id as users_id1_5_0_,
        users0_.email as email2_5_0_,
        users0_.name as name3_5_0_,
        users0_.password as password4_5_0_,
        users0_.picture as picture5_5_0_ 
    from
        users users0_ 
    where
        users0_.users_id=?
Hibernate: 
    select
        users0_.users_id as users_id1_5_0_,
        users0_.email as email2_5_0_,
        users0_.name as name3_5_0_,
        users0_.password as password4_5_0_,
        users0_.picture as picture5_5_0_ 
    from
        users users0_ 
    where
        users0_.users_id=?
==============댓글 사용 끝=============
=============게시글 읽기 컨트롤러 끝=====================&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;getCommentsList()를 실행했을 때에는 아무 쿼리도 실행되지 않았다. LazyLoading이기 때문에 당연하다.&lt;/p&gt;
&lt;p&gt;그 후 댓글을 dto로 전환하는 코드를 실행할 때 실제로 사용되므로 그 때 댓글 정보를 가져오는 쿼리문과 작성한 사용자 정보를 위한 쿼리문이 실행된다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1602071717801&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;=============게시글 읽기 컨트롤러 시작=====================
Hibernate: 
    select
        posts0_.posts_id as posts_id1_4_0_,
        posts0_.create_date as create_d2_4_0_,
        posts0_.created_date as created_3_4_0_,
        posts0_.modified_date as modified4_4_0_,
        posts0_.content as content5_4_0_,
        posts0_.picture as picture6_4_0_,
        posts0_.singer as singer7_4_0_,
        posts0_.song_name as song_nam8_4_0_,
        posts0_.users_id as users_id9_4_0_ 
    from
        posts posts0_ 
    where
        posts0_.posts_id=?
Hibernate: 
    select
        users0_.users_id as users_id1_5_0_,
        users0_.email as email2_5_0_,
        users0_.name as name3_5_0_,
        users0_.password as password4_5_0_,
        users0_.picture as picture5_5_0_ 
    from
        users users0_ 
    where
        users0_.users_id=?
Hibernate: 
    select
        likes0_.likes_id as likes_id1_3_,
        likes0_.posts_id as posts_id2_3_,
        likes0_.users_id as users_id3_3_ 
    from
        likes likes0_ 
    where
        likes0_.posts_id=?
=========댓글 가져오기 시작========
Hibernate: 
    select
        comments0_.comments_id as comments1_0_,
        comments0_.create_date as create_d2_0_,
        comments0_.created_date as created_3_0_,
        comments0_.modified_date as modified4_0_,
        comments0_.content as content5_0_,
        comments0_.posts_id as posts_id6_0_,
        comments0_.user_id as user_id7_0_ 
    from
        comments comments0_ 
    where
        comments0_.posts_id=?
=========댓글 가져오기 끝========
==============댓글 실제 사용=============
Hibernate: 
    select
        users0_.users_id as users_id1_5_0_,
        users0_.email as email2_5_0_,
        users0_.name as name3_5_0_,
        users0_.password as password4_5_0_,
        users0_.picture as picture5_5_0_ 
    from
        users users0_ 
    where
        users0_.users_id=?
Hibernate: 
    select
        users0_.users_id as users_id1_5_0_,
        users0_.email as email2_5_0_,
        users0_.name as name3_5_0_,
        users0_.password as password4_5_0_,
        users0_.picture as picture5_5_0_ 
    from
        users users0_ 
    where
        users0_.users_id=?
==============댓글 사용 끝=============
=============게시글 읽기 컨트롤러 끝=====================
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp; 다음은 쿼리를 직접 실행한 결과이다. 위의 결과와 다르다. commentService에서 댓글 목록을 가져올 때 직접 쿼리를 날리고 댓글을 전환할 때 작성자 정보를 따로 쿼리를 통해 가져온다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;궁금해서 실험해봤는데 쿼리 횟수가 동일하게 나왔다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;보고 넘어갈랬는데, 게시글 하나 읽는데 쿼리가 너무 많이 실행되는 것 같아 최적화를 하려 한다.&lt;/p&gt;
&lt;p&gt;기존 코드는 data jpa에서 제공하는 findBy~ 를 활용했었다. 그렇다보니 Lazy Loading으로 인해, 각 엔티티에 연결된 다른 엔티티의 정보를 가져올 때마다 select 쿼리가 날아갔다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;예를 들어 게시글에 작성한 댓글 목록을 select 쿼리를 통해 가져왔다 해도, 각 댓글들의 작성자에 대한 정보는 Lazy Loading으로 인해 다시 select 쿼리를 날려 각 user 정보를 가져와야 한다. 그렇다보니 댓글을 100명이 작성했다면 댓글목록 가져오기(1번) + 100명 각각에 대한 정보(100번)으로 총 101번의 쿼리가 날아갈 것이다.&lt;/p&gt;
&lt;p&gt;혼자 실행하는 프로젝트라 사용자가 많지 않아 현재는 괜찮지만, 만약 몇 천명이 사용하는 서비스를 이대로 제공하면 성능 이슈가 분명히 발생할 것이다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;다행히도 이런 상황에 대처하기 위해 fetch join이란 것이 있다. 댓글과 작성자 정보를 각각 가져오는 게 아니라, 댓글 정보를 가져옴과 동시에 작성자에 대한 정보까지 하나의 쿼리로 가져오는 것이다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;과정은 지루하니 생략하고 결과를 보여주자면 아래와 같다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;위에서 6개의 select 쿼리가 나간 것에 비해, 단 두 번으로 모든 정보를 가져온다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;첫 번째 쿼리는 게시글 정보 + 게시글 작성자 + 게시글 좋아요 목록을 가져오고&lt;/p&gt;
&lt;p&gt;두 번째 쿼리는 댓글 목록 + 댓글 작성자를 가져오는 쿼리이다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;만약 댓글을 100명이 달았다면 3 + 1 + 100 번의 쿼리를 날려야 할 것을 2번으로 줄였으니 비약적인 성능 상승이 이뤄졌다고 할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1602140905358&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;=============게시글 읽기 컨트롤러 시작=================
Hibernate: 
    select
        posts0_.posts_id as posts_id1_4_0_,
        users1_.users_id as users_id1_5_1_,
        likeslist2_.likes_id as likes_id1_3_2_,
        posts0_.create_date as create_d2_4_0_,
        posts0_.created_date as created_3_4_0_,
        posts0_.modified_date as modified4_4_0_,
        posts0_.content as content5_4_0_,
        posts0_.picture as picture6_4_0_,
        posts0_.singer as singer7_4_0_,
        posts0_.song_name as song_nam8_4_0_,
        posts0_.users_id as users_id9_4_0_,
        users1_.email as email2_5_1_,
        users1_.name as name3_5_1_,
        users1_.password as password4_5_1_,
        users1_.picture as picture5_5_1_,
        likeslist2_.posts_id as posts_id2_3_2_,
        likeslist2_.users_id as users_id3_3_2_,
        likeslist2_.posts_id as posts_id2_3_0__,
        likeslist2_.likes_id as likes_id1_3_0__ 
    from
        posts posts0_ 
    inner join
        users users1_ 
            on posts0_.users_id=users1_.users_id 
    left outer join
        likes likeslist2_ 
            on posts0_.posts_id=likeslist2_.posts_id 
    where
        posts0_.posts_id=?
Hibernate: 
    select
        comments0_.comments_id as comments1_0_0_,
        users1_.users_id as users_id1_5_1_,
        comments0_.create_date as create_d2_0_0_,
        comments0_.created_date as created_3_0_0_,
        comments0_.modified_date as modified4_0_0_,
        comments0_.content as content5_0_0_,
        comments0_.posts_id as posts_id6_0_0_,
        comments0_.user_id as user_id7_0_0_,
        users1_.email as email2_5_1_,
        users1_.name as name3_5_1_,
        users1_.password as password4_5_1_,
        users1_.picture as picture5_5_1_ 
    from
        comments comments0_ 
    inner join
        users users1_ 
            on comments0_.user_id=users1_.users_id 
    where
        comments0_.posts_id=?
=============게시글 읽기 컨트롤러 끝=================&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그래도 과정을 살짝 기록하자면 아래 두 코드이다. 위의 코드는 PostsRepository의 코드이고 아래는 CommentsRepository의 코드이다. 둘 다 기존에는 spring data jpa 인터페이스가 제공하는 findBy~&amp;nbsp; 메서드를 사용했었다. 아래와 같이 직접 fetch join 쿼리를 작성해 실행한 후 성능이 좋아졌음을 확인했다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UQMhv/btqKooRBkoB/nFixuc98K6Kc28rQ6rYLdk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UQMhv/btqKooRBkoB/nFixuc98K6Kc28rQ6rYLdk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UQMhv/btqKooRBkoB/nFixuc98K6Kc28rQ6rYLdk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUQMhv%2FbtqKooRBkoB%2FnFixuc98K6Kc28rQ6rYLdk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;718&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBGF3R/btqKrLSOLPh/5vLutkM575ULiXJKRejbEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBGF3R/btqKrLSOLPh/5vLutkM575ULiXJKRejbEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBGF3R/btqKrLSOLPh/5vLutkM575ULiXJKRejbEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBGF3R%2FbtqKrLSOLPh%2F5vLutkM575ULiXJKRejbEK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;718&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;원본 코드 :&amp;nbsp; &lt;a href=&quot;https://github.com/chosh95/Songstagram&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/chosh95/Songstagram&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1602141236763&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;object&quot; data-og-title=&quot;chosh95/Songstagram&quot; data-og-description=&quot;Spring Boot로 만들어보는 음악 SNS. Contribute to chosh95/Songstagram development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/chosh95/Songstagram&quot; data-og-url=&quot;https://github.com/chosh95/Songstagram&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cWRIHR/hyHL9VfCMt/f8mgt3GkH30D251bkHHoW0/img.jpg?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400,https://scrap.kakaocdn.net/dn/iozlS/hyHNDUGNh7/YYLGixoyfOZUFAtcFrRCbk/img.png?width=960&amp;amp;height=2000&amp;amp;face=0_0_960_2000,https://scrap.kakaocdn.net/dn/DFhLs/hyHNxtp3mx/Vg6dpKo4VubBHKwq2hei5K/img.png?width=960&amp;amp;height=1559&amp;amp;face=0_0_960_1559&quot;&gt;&lt;a href=&quot;https://github.com/chosh95/Songstagram&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/chosh95/Songstagram&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cWRIHR/hyHL9VfCMt/f8mgt3GkH30D251bkHHoW0/img.jpg?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400,https://scrap.kakaocdn.net/dn/iozlS/hyHNDUGNh7/YYLGixoyfOZUFAtcFrRCbk/img.png?width=960&amp;amp;height=2000&amp;amp;face=0_0_960_2000,https://scrap.kakaocdn.net/dn/DFhLs/hyHNxtp3mx/Vg6dpKo4VubBHKwq2hei5K/img.png?width=960&amp;amp;height=1559&amp;amp;face=0_0_960_1559');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;chosh95/Songstagram&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;Spring Boot로 만들어보는 음악 SNS. Contribute to chosh95/Songstagram development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로젝트/Songstagram</category>
      <author>cho____sh</author>
      <guid isPermaLink="true">https://chosh95.tistory.com/501</guid>
      <comments>https://chosh95.tistory.com/501#entry501comment</comments>
      <pubDate>Wed, 7 Oct 2020 21:08:13 +0900</pubDate>
    </item>
    <item>
      <title>[LeetCode] 5. Longest Palindromic Substring</title>
      <link>https://chosh95.tistory.com/500</link>
      <description>&lt;p&gt;&lt;span&gt;Given a string&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;s&lt;span&gt;, return&amp;nbsp;&lt;/span&gt;the longest palindromic substring&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;in&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;s&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;주어진 문자열에서 가장 긴 팰린드롬 문자열을 반환하라.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;이 문제를 시작으로 하루 종일 팰린드롬 문제만 풀었다.&lt;/p&gt;
&lt;p&gt;dp로 해결했는데, 풀기 전에는 어떻게 이걸 dp로 푸나 싶었다.&lt;/p&gt;
&lt;p&gt;힌트를 보고 해결 방법이 떠올랐다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;어떤 문자열 str이 팰린드롬이라면 이 문자열 str의 앞 뒤에 같은 문자를 추가했을때 그 문자열도 팰린드롬일 것이다.&lt;/p&gt;
&lt;p&gt;따라서 문자열에서 특정 위치 left, right의 문자가 같을 때 left+1 ~ right -1 까지의 문자열이 팰린드롬이라면 left ~ right도 팰린드롬일 것이다. 이 특징을 활용해 문제를 해결할 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;dp[left][right] : left~right 까지의 부분 문자열이 팰린드롬인가를 나타내는 boolean 값이라 하자.&lt;/p&gt;
&lt;p&gt;우선 한 글자짜리 문자열은 팰린드롬이다. dp[i][i]를 true로 설정해줌과 동시에 연속으로 같은 문자를 갖고 있는 부분 문자열도 처리해주자. str[i] == str[i+1]이면 dp[i][i+1] = true이다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그 후 left와 right의 차가 2가 되는 지점부터 차례대로 조사한다.&lt;/p&gt;
&lt;p&gt;차를 i, 시작점을 j라고 하면 str[j] == str[j + i]일때 이 사이의 문자열도 팰린드롬인지 검사하자.&lt;/p&gt;
&lt;p&gt;dp[j+1][j+i-1]이 true라면 dp[j][j + i]도 true가 된다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이런식으로 모든 부분 문자열을 조사하며 가장 길이가 긴 부분 문자열을 반환하면 된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;코드 원본 : &lt;a href=&quot;https://github.com/chosh95/STUDY/blob/master/LeetCode/Longest%20Palindromic%20Substring%202%ED%8A%B8.cpp&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/chosh95/STUDY/blob/master/LeetCode/Longest%20Palindromic%20Substring%202%ED%8A%B8.cpp&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1602069141454&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;object&quot; data-og-title=&quot;chosh95/STUDY&quot; data-og-description=&quot;프로그래밍 문제 및 알고리즘 정리. Contribute to chosh95/STUDY development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/chosh95/STUDY/blob/master/LeetCode/Longest%20Palindromic%20Substring%202%ED%8A%B8.cpp&quot; data-og-url=&quot;https://github.com/chosh95/STUDY&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bYWx7L/hyHMb5Nd6K/oJMX8KjTYEi6EmCTNeNhkK/img.jpg?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://github.com/chosh95/STUDY/blob/master/LeetCode/Longest%20Palindromic%20Substring%202%ED%8A%B8.cpp&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/chosh95/STUDY/blob/master/LeetCode/Longest%20Palindromic%20Substring%202%ED%8A%B8.cpp&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bYWx7L/hyHMb5Nd6K/oJMX8KjTYEi6EmCTNeNhkK/img.jpg?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;chosh95/STUDY&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;프로그래밍 문제 및 알고리즘 정리. Contribute to chosh95/STUDY development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;C++ 코드&lt;/p&gt;
&lt;pre id=&quot;code_1602069147003&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;string&amp;gt;
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;memory.h&amp;gt;
using namespace std;

class Solution {
public:
    string longestPalindrome(string s) {
        if (s.empty()) return &quot;&quot;;

        bool dp[1001][1001];
        memset(dp, false, sizeof(dp));

        string answer = &quot;&quot;;

        for (int i = 0; i &amp;lt; s.size(); i++) {
            dp[i][i] = true;
            if (answer.empty()) answer = s.substr(i, 1);
            if (i == s.size() - 1) break;
            if (s[i] == s[i + 1]) {
                dp[i][i + 1] = true;
                if (answer.length() &amp;lt; 2) answer = s.substr(i, 2);
            }
        }

        for (int i = 2; i &amp;lt; s.size(); i++)
            for (int j = 0; j + i &amp;lt; s.size(); j++)
                if (s[j] == s[j + i] &amp;amp;&amp;amp; dp[j + 1][j + i - 1]) {
                    dp[j][j + i] = true;
                    if (answer.length() &amp;lt; i + 1) {
                        answer = s.substr(j, i + 1);
                    }
                }


        return answer;
    }
};

int main()
{
    Solution s;
    cout &amp;lt;&amp;lt; s.longestPalindrome(&quot;cbbd&quot;);
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/LeetCode</category>
      <author>cho____sh</author>
      <guid isPermaLink="true">https://chosh95.tistory.com/500</guid>
      <comments>https://chosh95.tistory.com/500#entry500comment</comments>
      <pubDate>Wed, 7 Oct 2020 20:19:42 +0900</pubDate>
    </item>
    <item>
      <title>[백준] 팰린드롬 만들기 (1695번)</title>
      <link>https://chosh95.tistory.com/499</link>
      <description>&lt;h2&gt;문제&lt;/h2&gt;
&lt;p&gt;앞에서 뒤로 보나, 뒤에서 앞으로 보나 같은 수열을 팰린드롬 이라고 한다. 예를 들어 {1}, {1, 2, 1}, {1, 2, 2, 1}과 같은 수열은 팰린드롬 이지만, {1, 2, 3}, {1, 2, 3, 2} 등은 팰린드롬이 아니다.&lt;/p&gt;
&lt;p&gt;한 수열이 주어졌을 때, 이 수열에 최소 개수의 수를 끼워 넣어 팰린드롬을 만들려고 한다. 최소 몇 개의 수를 끼워 넣으면 되는지를 알아내는 프로그램을 작성하시오.&lt;/p&gt;
&lt;h2&gt;입력&lt;/h2&gt;
&lt;p&gt;첫째 줄에 수열의 길이 N(1&amp;le;N&amp;le;5,000)이 주어진다. 다음 줄에는 N개의 수열을 이루는 수들이 주어진다. 각 수들은 int 범위이다.&lt;/p&gt;
&lt;h2&gt;출력&lt;/h2&gt;
&lt;p&gt;첫째 줄에 끼워 넣을 수들의 최소 개수를 출력한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;수열의 중간에 원하는 수를 추가해서 얻을 수 있는 가장 짧은 팰린드롬을 구해야 한다.&lt;/p&gt;
&lt;p&gt;예를들어 1 2 3 1이라면 중간에 2 또는 3을 추가해서 12321, 13231 이라는 팰린드롬 수열을 구할 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;dp를 이용해 해결할 수 있다.&lt;/p&gt;
&lt;p&gt;dp[start][end] : start ~ end 지점에서 끼워 넣을 수의 최소 개수라고 하자.&lt;/p&gt;
&lt;p&gt;이미 팰린드롬이라면 0일 것이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;만약 start와 end인덱스에 해당하는 수가 같다면 dp[start][end] = dp[start+1][end-1]이 될 것이다.&lt;/p&gt;
&lt;p&gt;다르다면, dp[start][end] = min(dp[start+1][end, dp[start][end-1]) + 1 이 될 것이다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이 점화식이 성립하도록 적절하게 구현해주자.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;코드 원본 : &lt;a href=&quot;https://github.com/chosh95/STUDY/blob/master/BaekJoon/2020/%ED%8C%B0%EB%A6%B0%EB%93%9C%EB%A1%AC%20%EB%A7%8C%EB%93%A4%EA%B8%B0%20(1695%EB%B2%88).cpp&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/chosh95/STUDY/blob/master/BaekJoon/2020/%ED%8C%B0%EB%A6%B0%EB%93%9C%EB%A1%AC%20%EB%A7%8C%EB%93%A4%EA%B8%B0%20(1695%EB%B2%88).cpp&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1602068582179&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;object&quot; data-og-title=&quot;chosh95/STUDY&quot; data-og-description=&quot;프로그래밍 문제 및 알고리즘 정리. Contribute to chosh95/STUDY development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/chosh95/STUDY/blob/master/BaekJoon/2020/%ED%8C%B0%EB%A6%B0%EB%93%9C%EB%A1%AC%20%EB%A7%8C%EB%93%A4%EA%B8%B0%20(1695%EB%B2%88).cpp&quot; data-og-url=&quot;https://github.com/chosh95/STUDY&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/FiFXB/hyHMb5MxMn/o08k4Ifsyy2rfjIjtFTy6K/img.jpg?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://github.com/chosh95/STUDY/blob/master/BaekJoon/2020/%ED%8C%B0%EB%A6%B0%EB%93%9C%EB%A1%AC%20%EB%A7%8C%EB%93%A4%EA%B8%B0%20(1695%EB%B2%88).cpp&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/chosh95/STUDY/blob/master/BaekJoon/2020/%ED%8C%B0%EB%A6%B0%EB%93%9C%EB%A1%AC%20%EB%A7%8C%EB%93%A4%EA%B8%B0%20(1695%EB%B2%88).cpp&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/FiFXB/hyHMb5MxMn/o08k4Ifsyy2rfjIjtFTy6K/img.jpg?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;chosh95/STUDY&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;프로그래밍 문제 및 알고리즘 정리. Contribute to chosh95/STUDY development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;C++ 코드&lt;/p&gt;
&lt;pre id=&quot;code_1602068585619&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;algorithm&amp;gt;
using namespace std;

int N;
int p[5001];
int dp[5001][5001];

int dfs(int start, int end) {
	if (start &amp;gt;= end) return 0;

	if (dp[start][end] != 0) return dp[start][end];

	int cur = 987654321;
	if (p[start] == p[end])
		cur = min(cur, dfs(start + 1, end - 1));
	else {
		cur = min(dfs(start,end-1) + 1, dfs(start + 1, end) + 1);
	}
		
	return dp[start][end] = cur;
}

int main()
{
	cin &amp;gt;&amp;gt; N;
	for (int i = 0; i &amp;lt; N; i++)
		cin &amp;gt;&amp;gt; p[i];

	cout &amp;lt;&amp;lt; dfs(0, N - 1);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/백준</category>
      <author>cho____sh</author>
      <guid isPermaLink="true">https://chosh95.tistory.com/499</guid>
      <comments>https://chosh95.tistory.com/499#entry499comment</comments>
      <pubDate>Wed, 7 Oct 2020 20:07:55 +0900</pubDate>
    </item>
    <item>
      <title>[백준] 팰린드롬 만들기 (1254번)</title>
      <link>https://chosh95.tistory.com/498</link>
      <description>&lt;h2&gt;문제&lt;/h2&gt;
&lt;p&gt;동호와 규완이는 212호에서 문자열에 대해 공부하고 있다. 규완이는 팰린드롬을 엄청나게 좋아한다. 팰린드롬이란 앞에서부터 읽으나 뒤에서부터 읽으나 같게 읽히는 문자열을 말한다.&lt;/p&gt;
&lt;p&gt;동호는 규완이를 위한 깜짝 선물을 준비했다. 동호는 규완이가 적어놓고 간 문자열 S에 0개 이상의 문자를 문자열 뒤에 추가해서 팰린드롬을 만들려고 한다. 동호는 가능하면 가장 짧은 문자열을 만들려고 한다.&lt;/p&gt;
&lt;p&gt;동호가 만들 수 있는 가장 짧은 팰린드롬의 길이를 출력하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;h2&gt;입력&lt;/h2&gt;
&lt;p&gt;첫째 줄에 문자열 S가 주어진다. S의 길이는 최대 1000이다.&lt;/p&gt;
&lt;h2&gt;출력&lt;/h2&gt;
&lt;p&gt;첫째 줄에 동호가 만들 수 있는 가장 짧은 팰린드롬의 길이를 출력한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;문자열의 끝에 문자를 추가해 팰린드롬을 만드는 문제이다.&lt;/p&gt;
&lt;p&gt;중간에도 추가가 가능한 줄 알고 뻘짓을 했다.&lt;/p&gt;
&lt;p&gt;끝에만 문자를 추가할 수 있기 때문에 aabcaa인 경우에 aabcaacbaa가 답이 된다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;해결방법은 인덱스가 0인 지점부터 차례대로 조사하며 팰린드롬이 되는 최소한의 시작 위치를 찾는 것이다.&lt;/p&gt;
&lt;p&gt;aabcaa인 경우에는 맨 뒤의 aa만 팰린드롬이 가능하다 따라서 aa는 그대로 두고 나머지 aabc만 뒤집어서 추가해주면 가장 짧은 팰린드롬 문자열이 생성된다.&lt;/p&gt;
&lt;p&gt;aabcba를 생각해보자. 맨 앞의 a를 제외하고 나머지 abcba가 팰린드롬이므로 마지막에 a만 추가해주면 팰린드롬이 성립한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이에 맞게 구현해주자. 시작 위치부터 차례대로 조사하며 특정 위치부터 마지막까지의 부분 문자열이 팰린드롬이라면, 전체 길이에서 시작 위치에 해당하는 길이만큼 더해서 출력하면 된다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;코드 원본 : &lt;a href=&quot;https://github.com/chosh95/STUDY/blob/master/BaekJoon/2020/%ED%8C%B0%EB%A6%B0%EB%93%9C%EB%A1%AC%20%EB%A7%8C%EB%93%A4%EA%B8%B0%20(1254%EB%B2%88).cpp&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/chosh95/STUDY/blob/master/BaekJoon/2020/%ED%8C%B0%EB%A6%B0%EB%93%9C%EB%A1%AC%20%EB%A7%8C%EB%93%A4%EA%B8%B0%20(1254%EB%B2%88).cpp&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1602068133444&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;object&quot; data-og-title=&quot;chosh95/STUDY&quot; data-og-description=&quot;프로그래밍 문제 및 알고리즘 정리. Contribute to chosh95/STUDY development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/chosh95/STUDY/blob/master/BaekJoon/2020/%ED%8C%B0%EB%A6%B0%EB%93%9C%EB%A1%AC%20%EB%A7%8C%EB%93%A4%EA%B8%B0%20(1254%EB%B2%88).cpp&quot; data-og-url=&quot;https://github.com/chosh95/STUDY&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Ei1uv/hyHMiqi3cl/CxoNfpTaM1WFLFi1iaB9Q1/img.jpg?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://github.com/chosh95/STUDY/blob/master/BaekJoon/2020/%ED%8C%B0%EB%A6%B0%EB%93%9C%EB%A1%AC%20%EB%A7%8C%EB%93%A4%EA%B8%B0%20(1254%EB%B2%88).cpp&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/chosh95/STUDY/blob/master/BaekJoon/2020/%ED%8C%B0%EB%A6%B0%EB%93%9C%EB%A1%AC%20%EB%A7%8C%EB%93%A4%EA%B8%B0%20(1254%EB%B2%88).cpp&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Ei1uv/hyHMiqi3cl/CxoNfpTaM1WFLFi1iaB9Q1/img.jpg?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;chosh95/STUDY&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;프로그래밍 문제 및 알고리즘 정리. Contribute to chosh95/STUDY development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;C++ 코드&lt;/p&gt;
&lt;pre id=&quot;code_1602068136801&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;algorithm&amp;gt;
#include &amp;lt;string&amp;gt;
#include &amp;lt;memory.h&amp;gt;
using namespace std;
string str;
int n = str.size();

bool isPalin(int idx) {
	int half = (n - idx) / 2;
	for (int i = 0; i &amp;lt; half; i++) {
		if (str[idx + i] != str[n - 1 - i]) return false;
	}
	return true;
}

int main()
{
	cin &amp;gt;&amp;gt; str;
	n = str.size();

	for (int i = 0; i &amp;lt; n; i++) {
		if (isPalin(i)) {
			cout &amp;lt;&amp;lt; n + i;
			return 0;
		}
	}
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/백준</category>
      <author>cho____sh</author>
      <guid isPermaLink="true">https://chosh95.tistory.com/498</guid>
      <comments>https://chosh95.tistory.com/498#entry498comment</comments>
      <pubDate>Wed, 7 Oct 2020 20:02:10 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 보석 쇼핑</title>
      <link>https://chosh95.tistory.com/497</link>
      <description>&lt;p&gt;&lt;b&gt;[본 문제는 정확성과 효율성 테스트 각각 점수가 있는 문제입니다.]&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;개발자 출신으로 세계 최고의 갑부가 된&lt;span&gt;&amp;nbsp;&lt;/span&gt;어피치는 스트레스를 받을 때면 이를 풀기 위해 오프라인 매장에 쇼핑을 하러 가곤 합니다.&lt;br /&gt;어피치는 쇼핑을 할 때면 매장 진열대의 특정 범위의 물건들을 모두 싹쓸이 구매하는 습관이 있습니다.&lt;br /&gt;어느 날 스트레스를 풀기 위해 보석 매장에 쇼핑을 하러 간 어피치는 이전처럼 진열대의 특정 범위의 보석을 모두 구매하되 특별히 아래 목적을 달성하고 싶었습니다.&lt;br /&gt;진열된 모든 종류의 보석을 적어도 1개 이상 포함하는 가장 짧은 구간을 찾아서 구매&lt;/p&gt;
&lt;p&gt;예를 들어 아래 진열대는 4종류의 보석(RUBY, DIA, EMERALD, SAPPHIRE) 8개가 진열된 예시입니다.&lt;/p&gt;
&lt;p&gt;진열대 번호12345678&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;보석 이름&lt;/td&gt;
&lt;td&gt;DIA&lt;/td&gt;
&lt;td&gt;RUBY&lt;/td&gt;
&lt;td&gt;&lt;b&gt;RUBY&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;DIA&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;DIA&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;EMERALD&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;SAPPHIRE&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;DIA&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;진열대의 3번부터 7번까지 5개의 보석을 구매하면 모든 종류의 보석을 적어도 하나 이상씩 포함하게 됩니다.&lt;/p&gt;
&lt;p&gt;진열대의 3, 4, 6, 7번의 보석만 구매하는 것은 중간에 특정 구간(5번)이 빠지게 되므로 어피치의 쇼핑 습관에 맞지 않습니다.&lt;/p&gt;
&lt;p&gt;진열대 번호 순서대로 보석들의 이름이 저장된 배열 gems가 매개변수로 주어집니다. 이때 모든 보석을 하나 이상 포함하는 가장 짧은 구간을 찾아서 return 하도록 solution 함수를 완성해주세요.&lt;br /&gt;가장 짧은 구간의&lt;span&gt;&amp;nbsp;&lt;/span&gt;시작 진열대 번호와&lt;span&gt;&amp;nbsp;&lt;/span&gt;끝 진열대 번호를 차례대로 배열에 담아서 return 하도록 하며, 만약 가장 짧은 구간이 여러 개라면&lt;span&gt;&amp;nbsp;&lt;/span&gt;시작 진열대 번호가 가장 작은 구간을 return 합니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;[제한사항]&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;gems 배열의 크기는 1 이상 100,000 이하입니다.
&lt;ul&gt;
&lt;li&gt;gems 배열의 각 원소는 진열대에 나열된 보석을 나타냅니다.&lt;/li&gt;
&lt;li&gt;gems 배열에는 1번 진열대부터 진열대 번호 순서대로 보석이름이 차례대로 저장되어 있습니다.&lt;/li&gt;
&lt;li&gt;gems 배열의 각 원소는 길이가 1 이상 10 이하인 알파벳 대문자로만 구성된 문자열입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr style=&quot;box-sizing: content-box; height: 0px; overflow: visible; margin: 1.5rem 0px; border-width: 0.0625rem 0px 0px; border-color: #172334; border-image: initial; color: #b2c0cc; font-family: Inter, NotoSansKR, 'Helvetica Neue', Helvetica, Arial, '맑은 고딕', 'malgun gothic', 돋움, Dotum, sans-serif, 'Apple Color Emoji', 'Noto Color Emoji'; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: #263747; text-decoration-style: initial; text-decoration-color: initial; border-style: solid initial initial initial;&quot; /&gt;
&lt;p&gt;&lt;b&gt;입출력 예&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;gemsresult&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;[&quot;DIA&quot;, &quot;RUBY&quot;, &quot;RUBY&quot;, &quot;DIA&quot;, &quot;DIA&quot;, &quot;EMERALD&quot;, &quot;SAPPHIRE&quot;, &quot;DIA&quot;]&lt;/td&gt;
&lt;td&gt;[3, 7]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;[&quot;AA&quot;, &quot;AB&quot;, &quot;AC&quot;, &quot;AA&quot;, &quot;AC&quot;]&lt;/td&gt;
&lt;td&gt;[1, 3]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;[&quot;XYZ&quot;, &quot;XYZ&quot;, &quot;XYZ&quot;]&lt;/td&gt;
&lt;td&gt;[1, 1]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;[&quot;ZZZ&quot;, &quot;YYY&quot;, &quot;NNNN&quot;, &quot;YYY&quot;, &quot;BBB&quot;]&lt;/td&gt;
&lt;td&gt;[1, 5]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;b&gt;입출력 예에 대한 설명&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #1&lt;/b&gt;&lt;br /&gt;문제 예시와 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #2&lt;/b&gt;&lt;br /&gt;3종류의 보석(AA, AB, AC)을 모두 포함하는 가장 짧은 구간은 [1, 3], [2, 4]가 있습니다.&lt;br /&gt;시작 진열대 번호가 더 작은 [1, 3]을 return 해주어야 합니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #3&lt;/b&gt;&lt;br /&gt;1종류의 보석(XYZ)을 포함하는 가장 짧은 구간은 [1, 1], [2, 2], [3, 3]이 있습니다.&lt;br /&gt;시작 진열대 번호가 가장 작은 [1, 1]을 return 해주어야 합니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #4&lt;/b&gt;&lt;br /&gt;4종류의 보석(ZZZ, YYY, NNNN, BBB)을 모두 포함하는 구간은 [1, 5]가 유일합니다.&lt;br /&gt;그러므로 [1, 5]를 return 해주어야 합니다.&lt;/p&gt;
&lt;p&gt;※ 공지 - 2020년 7월 21일 테스트케이스가 추가되었습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;연속된 보석을 선택해서 모든 종류의 보석을 고르는 문제이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;set을 이용한 완전 탐색을 통해 문제를 풀었다가 효율성에서 시간초과가 떠서 다시 풀었다.&lt;/p&gt;
&lt;p&gt;다시 map을 이용한 투포인터 알고리즘으로 해결했다.&lt;/p&gt;
&lt;p&gt;제일 왼쪽부터 보석을 하나씩 고르면서 모든 보석을 골랐을 때 왼쪽 포인터를 1씩 증가시키면서 가장 짧은 길이의 구간을 구하면 된다. 변수명에 tmp를 너무 많이 썼는데, 잘 이해하길 바란다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;코드 원본 : &lt;a href=&quot;https://github.com/chosh95/STUDY/blob/839a492e04155e5b7dcda7bb9941dd4a212dbc46/Programmers/%EB%B3%B4%EC%84%9D%20%EC%87%BC%ED%95%91.cpp&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/chosh95/STUDY/blob/839a492e04155e5b7dcda7bb9941dd4a212dbc46/Programmers/%EB%B3%B4%EC%84%9D%20%EC%87%BC%ED%95%91.cpp&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1601364269449&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;object&quot; data-og-title=&quot;chosh95/STUDY&quot; data-og-description=&quot;프로그래밍 문제 및 알고리즘 정리. Contribute to chosh95/STUDY development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/chosh95/STUDY/blob/839a492e04155e5b7dcda7bb9941dd4a212dbc46/Programmers/%EB%B3%B4%EC%84%9D%20%EC%87%BC%ED%95%91.cpp&quot; data-og-url=&quot;https://github.com/chosh95/STUDY&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cpIDOs/hyHE5FAXEi/nayGzOCTkAUUfdrsL0rg81/img.jpg?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://github.com/chosh95/STUDY/blob/839a492e04155e5b7dcda7bb9941dd4a212dbc46/Programmers/%EB%B3%B4%EC%84%9D%20%EC%87%BC%ED%95%91.cpp&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/chosh95/STUDY/blob/839a492e04155e5b7dcda7bb9941dd4a212dbc46/Programmers/%EB%B3%B4%EC%84%9D%20%EC%87%BC%ED%95%91.cpp&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cpIDOs/hyHE5FAXEi/nayGzOCTkAUUfdrsL0rg81/img.jpg?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;chosh95/STUDY&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;프로그래밍 문제 및 알고리즘 정리. Contribute to chosh95/STUDY development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;C++ 코드&lt;/p&gt;
&lt;pre id=&quot;code_1601364276865&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;map&amp;gt;
#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;
using namespace std;

vector&amp;lt;int&amp;gt; solution(vector&amp;lt;string&amp;gt; gems) {
    vector&amp;lt;int&amp;gt; answer;
    map&amp;lt;string, int&amp;gt; origin, tmp;
    for (int i = 0; i &amp;lt; gems.size(); i++)
        origin.insert({gems[i], 1});
    
    int minCnt = 987654321, startIdx = 0, endIdx = 0;
    int startTmp = 0;
    for (int i = 0; i &amp;lt; gems.size(); i++) {
        tmp[gems[i]]++;
        while(tmp.size() == origin.size()) {
            if (minCnt &amp;gt; i - startTmp) {
                minCnt = i - startTmp;
                startIdx = startTmp+1;
                endIdx = i+1;
            }
            if (tmp[gems[startTmp]] == 1) tmp.erase(gems[startTmp]);
            else tmp[gems[startTmp]]--;
            startTmp++;
        }
    }

    answer.push_back(startIdx);
    answer.push_back(endIdx);
    return answer;
}

int main()
{
    vector&amp;lt;int&amp;gt; res = solution({ &quot;AA&quot;,&quot;AB&quot;,&quot;AC&quot;,&quot;AB&quot;,&quot;AA&quot; });
    for (int i : res) {
        cout &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &quot; &quot;;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/프로그래머스</category>
      <author>cho____sh</author>
      <guid isPermaLink="true">https://chosh95.tistory.com/497</guid>
      <comments>https://chosh95.tistory.com/497#entry497comment</comments>
      <pubDate>Tue, 29 Sep 2020 16:28:34 +0900</pubDate>
    </item>
  </channel>
</rss>