<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Crackerjack's IT shack</title>
    <link>https://crackerjacks.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Wed, 5 Aug 2026 12:43:31 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>cra4ckerjack</managingEditor>
    <item>
      <title>알고리즘 풀이 백준(BOI) 5373) 큐빙 (Python)</title>
      <link>https://crackerjacks.tistory.com/19</link>
      <description>&lt;h2 style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;백준(BOI) 5373 - 큐빙&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr style=&quot;border: none; font-size: 0px; line-height: 0; height: 20px; margin: 20px auto; background: url('https://t1.daumcdn.net/keditor/dist/0.4.0/image/divider-line.svg') 0px -160px / 200px 200px no-repeat #ffffff; cursor: pointer !important; width: 200px; color: #666666; font-family: 'Noto Sans', sans-serif; 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; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&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;figure id=&quot;og_1594690644021&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;5373번: 큐빙&quot; data-og-description=&quot;문제 루빅스 큐브는 삼차원 퍼즐이다. 보통 루빅스 큐브는 3&amp;times;3&amp;times;3개의 작은 정육면체로 이루어져 있다. 퍼즐을 풀려면 각 면에 있는 아홉 개의 작은 정육면체의 색이 동일해야 한다. 큐브는 각 면&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/5373&quot; data-og-url=&quot;https://www.acmicpc.net/problem/5373&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/eWhsw/hyGLgHggaw/4kOCPF2rEQaIjifP1LmMBK/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/5373&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/5373&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/eWhsw/hyGLgHggaw/4kOCPF2rEQaIjifP1LmMBK/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;&gt;5373번: 큐빙&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;문제 루빅스 큐브는 삼차원 퍼즐이다. 보통 루빅스 큐브는 3&amp;times;3&amp;times;3개의 작은 정육면체로 이루어져 있다. 퍼즐을 풀려면 각 면에 있는 아홉 개의 작은 정육면체의 색이 동일해야 한다. 큐브는 각 면&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;www.acmicpc.net&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;[ 문제풀이 ]&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: justify;&quot;&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/7oBYz/btqFDwZC4pI/HSswfBu2u4emwt7KkE6MNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7oBYz/btqFDwZC4pI/HSswfBu2u4emwt7KkE6MNK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7oBYz/btqFDwZC4pI/HSswfBu2u4emwt7KkE6MNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7oBYz%2FbtqFDwZC4pI%2FHSswfBu2u4emwt7KkE6MNK%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 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;큐빙은 큐브를 정해진 입력대로 회전시켜 윗면의 상태를 출력하는 문제로 대표적인 시뮬레이션 문제이다. 큐브 문제는 별다른 핵심적인 풀이 방법이 없는 것 같다. 그냥 주어진대로 잘 구현만 하면 된다. &lt;s&gt;그런데 그게 맘처럼 구현이 잘 안 되는 게 문제다.&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;이 문제는 큐브를 돌리는 방법, 즉 정면을 바라보고 총 12가지 방법(U+, D+, F+, B+, R+, L+), (U-, D-, F-, B-, R-, L-)을 구현하면 된다. &lt;span style=&quot;color: #ee2323;&quot;&gt;한 가지 팁&lt;span style=&quot;color: #333333;&quot;&gt;은 &lt;u&gt;반시계 방향( - ) 은 굳이 따로 구현해줄 필요가 없다&lt;/u&gt;&lt;/span&gt;.&lt;/span&gt; 시계 방향으로 3번 반복해서 돌리면 반시계 방향으로 한 번 돌린 것과 결과가 같기 때문이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;필자는 시계 방향( + ) 이 입력으로 들어올 경우 count라는 변수에 1을, 반시계 방향( - ) 이 입력으로 들어올 경우 3을 대입시켜 count 횟수만큼 move() 메소드를 돌려주었다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;큐브는 3차원 배열로 구현하였다. 상단에 꼭 주석으로 큐브의 초기값을 그려보도록 하자. 참고로 &lt;a href=&quot;https://rubiks-cube-solver.com/fr/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이 사이트&lt;/a&gt;에 들어가면 큐브를 실제로 돌려보며 비교하면서 보다 편한 디버깅을 할 수 있다. 사이트에서 초기값만 문제에서 요구하는대로 바꿔주고 입력대로 돌려보면서 비교하면 된다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&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/cUTR9k/btqFDaoYLE0/JtTCJLoB7RnRbV4vktzHA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUTR9k/btqFDaoYLE0/JtTCJLoB7RnRbV4vktzHA1/img.png&quot; data-alt=&quot;사이트의 모습, 필자는 큐브 모양을 구현할 모양대로 바꿔주었다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUTR9k/btqFDaoYLE0/JtTCJLoB7RnRbV4vktzHA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUTR9k%2FbtqFDaoYLE0%2FJtTCJLoB7RnRbV4vktzHA1%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;figcaption&gt;사이트의 모습, 필자는 큐브 모양을 구현할 모양대로 바꿔주었다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #9d9d9d;&quot;&gt;&lt;s&gt;&lt;i&gt;시험장에서는 사용할 수 없으니 풀 때는 그냥 풀고 참고 목적으로만 쓰자.&lt;/i&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;큐브 문제는 별다른 로직 없이 쌩구현이기 때문에 코드 하나하나가 치명적이다. 때문에 움직임을 구현할 때 상당한 신중함을 기울여야 한다. 배열 인덱스 하나 잘 못 입력하면 찾는데 엄청 고생한다. 때문에 이 문제는 테스트 케이스 4번까지 통과하면 웬만하면 통과하겠지만, 그렇지 않다면 디버깅을 하여 오류를 찾아내는 과정 또한 상당히 중요하다. 윗면의 출력이야 문제에서 주어지니 당연히 구현해 놨겠지만, 디버깅을 위해 큐브 전체를 출력해주는 메소드도 만들어주는 것이 좋다.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;text-align: justify;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #456771;&quot;&gt;1. 큐브를 배열에 구현한다. 문제에서 주어진 대로 초기화한다.&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp; 필자는 다음과 같이 큐브를 구현하고자 하였다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1594691494317&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;&quot;&quot;
               [2]
               WWW            
               WWW
               WWW
          [3]  [0]  [4]  [5]
          GGG  RRR  BBB  OOO
          GGG  RRR  BBB  OOO
          GGG  RRR  BBB  OOO
               [1]
               YYY
               YYY
               YYY  
&quot;&quot;&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;인덱스 0은 앞면, 5는 후면, 1은 밑면, 2는 윗면, 3은 왼쪽면, 4는 오른쪽면이다. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;배열을 생성해주고 초기화한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1594691536821&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    cube = [[] for _ in range(6)]
    for _ in range(3):
        cube[0].append(['r','r','r']); cube[1].append(['y','y','y']); cube[2].append(['w','w','w'])
        cube[3].append(['g','g','g']); cube[4].append(['b','b','b']); cube[5].append(['o','o','o'])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;이렇게 하면 문제에서 주어진 초기 상황과 똑같아진다. 배열의 인덱스를 무엇으로 하는지에 따라 큐브의 움직임 구현을 다르게 해야 하기 때문에 생각을 잘해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;다음은 입력을 받고 메소드에 넣어주면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1594691747457&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;...
...
	comm = list(map(str, input().split()))
...
...
	while comm: 
		go(cube,comm.pop(0))
	printResult(cube)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;입력은 큐에 받아 비워질 때까지 메소드를 돌려준다. 마지막에는 결과값(윗면)을 출력해준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;text-align: justify;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #456771;&quot;&gt;2. 입력받은 움직임의 방향(시계방향, 반시계 방향)을 count로 치환해준다.&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;앞서 말한 대로 반시계는 시계방향 * 3이다. 때문에 반시계 방향을 따로 구현해줄 필요가 없다. 방향을 count로 치환해주고 움직임을 구현하는 메소드로 넘긴다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1594691868982&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def go(cube,comm):
    direction, count = comm
    count = 1 if count == '+' else 3
    for _ in range(count): move(cube,direction)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;text-align: justify;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #456771;&quot;&gt;3. 움직임을 구현해준다.&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;문제의 가장 핵심인 시뮬레이션이다. &lt;s&gt;그냥 노가다&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;코드를 작성하고 잘 풀었겠지 하고 돌려보면 결과가 항상 이상하다. 99%는 인덱스의 문제였고 1%는 필자가 회전하는 면의 회전, 예를 들어 왼쪽 시계방향(L+)이라면 초록 부분을 시계방향으로 돌려주는 메소드를 실수로 3번씩 해주는 바람에 시간을 많이 낭비했다. 큐브 전체 면을 디버깅하고 나서야 알았는데, &lt;b&gt;앞서 말한 대로 이 문제는 디버깅이 매우 매우 중요하다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;필자는 디버깅을 위해 다음과 같은 함수를 작성하고, 큐에서 명령을 빼낼 때마다 호출했다.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1594692100418&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    while comm: 
        go(cube,comm.pop(0))
        print(&quot;count : &quot; , count)
        count+=1
        temp(cube)
    #printResult(cube) 주석처리
        &lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;temp()메소드가 그것이다.&amp;nbsp; 다음과 같이 생겼고 다음과 같이 출력된다.&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1594692160956&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def temp(cube):
    for i in range(3):
        for j in range(3):
            print(cube[2][i][j], end=&quot;&quot;)
        print()

    for i in range(3):
        for t in range(4):
            for j in range(3):
                if t == 0:
                    print(cube[3][i][j], end=&quot;&quot;)
                elif t == 1:
                    print(cube[0][i][j], end=&quot;&quot;)
                elif t == 2:
                    print(cube[4][i][j], end=&quot;&quot;)
                elif t == 3:
                    print(cube[5][i][j], end=&quot;&quot;)
            print(&quot; &quot;, end=&quot; &quot;)
        print()
    
    for i in range(3):
        for j in range(3):
            print(cube[1][i][j], end=&quot;&quot;)
        print()
    print()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 다음은 문제에서 주어진 테스트 케이스 중 세 번째 테스트 케이스를 넣었을 경우이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1594692206621&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Input &amp;gt;&amp;gt;
1
4
U- D- L+ R+&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1594692254493&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Output &amp;gt;&amp;gt;

count :  1
www
www
www
ooo  ggg  rrr  bbb  
ggg  rrr  bbb  ooo  
ggg  rrr  bbb  ooo  
yyy
yyy
yyy

count :  2
www
www
www
ooo  ggg  rrr  bbb  
ggg  rrr  bbb  ooo  
rrr  bbb  ooo  ggg  
yyy
yyy
yyy

count :  3
gww
oww
bww
rgo  wgg  rrr  bby  
rgo  wrr  bbb  ooy  
rgo  wbb  ooo  ggy  
gyy
ryy
byy

count :  4
gwg
owr
bwb
rgo  wgy  obr  wby  
rgo  wry  obr  woy  
rgo  wby  obr  wgy  
gyg
ryo
byb&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;이 문제에서 디버깅은 정말 정말 중요하다. 처음부터 통과해버리면 필요 없겠지만 정말 헤매고 헤맨다면 위에서 말한 사이트와 비교해가면서 디버깅을 해보도록 하자.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;움직임은 그냥 인덱스끼리 바꿔주는 방식으로 구현하였다. 면의 움직임(L+ 일 경우 초록 면의 움직임)은 모든 면이 다 같이 쓸 수 있으므로 따로 함수로 빼서 작성하였다.&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;이 문제는 L과 R이 구현하기 가장 어렵다. 인덱스를 거꾸로 받는 경우가 있기 때문이다. L만 보면 다음과 같고 다른 움직임도 위와 동일한 구조를 지닌다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1594692537223&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;...
...
	elif direction == 'L': 
          temp = [cube[0][0][0], cube[0][1][0], cube[0][2][0]]
          cube[0][0][0], cube[0][1][0], cube[0][2][0] = cube[2][0][0], cube[2][1][0], cube[2][2][0]
          cube[2][0][0], cube[2][1][0], cube[2][2][0] = cube[5][2][2], cube[5][1][2], cube[5][0][2]
          cube[5][0][2], cube[5][1][2], cube[5][2][2] = cube[1][2][0], cube[1][1][0], cube[1][0][0]
          cube[1][0][0], cube[1][1][0], cube[1][2][0] = temp
          moveDimension(cube,3)
...
...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;해당 면의 회전은 moveDimension()에서 수행한다. 처음에 3바퀴를 회전시켰는데 생각해보니 2바퀴더라 -_-&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1594692600150&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def moveDimension(cube,index):
    for _ in range(2):
        temp = cube[index][0][0]
        cube[index][0][0] = cube[index][1][0]
        cube[index][1][0] = cube[index][2][0]
        cube[index][2][0] = cube[index][2][1]
        cube[index][2][1] = cube[index][2][2]
        cube[index][2][2] = cube[index][1][2]
        cube[index][1][2] = cube[index][0][2]
        cube[index][0][2] = cube[index][0][1]
        cube[index][0][1] = temp&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;몇 번의 시행착오 끝에 한 번에 통과하였다. 솔직히 이 문제를 시간 안에 풀 수 있을지 의문이다. 쌩구현일 뿐더러 오류 하나하나가 치명적이기 때문이다. 디버깅을 체계적으로 잘하는 법의 필요성을 크게 느꼈던 문제였던 것 같다.&lt;/span&gt;&lt;/p&gt;
&lt;hr style=&quot;margin: 20px auto 0px; border: none; cursor: pointer !important; z-index: 1; font-size: 0px; line-height: 0; background: url('../image/divider-line.svg') center -362px / 200px 420px no-repeat; width: 200px; height: 19px; padding: 18px 20px 17px; color: #333333; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; 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; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;[ 전체 소스코드 ]&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1593676991429&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;&quot;&quot;
               [2]
               WWW            
               WWW
               WWW
          [3]  [0]  [4]  [5]
          GGG  RRR  BBB  OOO
          GGG  RRR  BBB  OOO
          GGG  RRR  BBB  OOO
               [1]
               YYY
               YYY
               YYY  
&quot;&quot;&quot;
def printResult(cube):
    for i in range(3):
        for j in range(3):
            print(cube[2][i][j],end=&quot;&quot;)
        print()

def moveDimension(cube,index):
    for _ in range(2):
        temp = cube[index][0][0]
        cube[index][0][0] = cube[index][1][0]
        cube[index][1][0] = cube[index][2][0]
        cube[index][2][0] = cube[index][2][1]
        cube[index][2][1] = cube[index][2][2]
        cube[index][2][2] = cube[index][1][2]
        cube[index][1][2] = cube[index][0][2]
        cube[index][0][2] = cube[index][0][1]
        cube[index][0][1] = temp
    

def move(cube, direction):
    if direction == 'U':
        temp = cube[0][0]
        cube[0][0] = cube[4][0]
        cube[4][0] = cube[5][0]
        cube[5][0] = cube[3][0]
        cube[3][0] = temp
        moveDimension(cube,2)
        
    elif direction == 'D': 
        temp = cube[0][2]
        cube[0][2] = cube[3][2]
        cube[3][2] = cube[5][2]
        cube[5][2] = cube[4][2]
        cube[4][2] = temp
        moveDimension(cube,1)
        
    elif direction == 'F': 
        temp = cube[2][2]
        cube[2][2] = [cube[3][2][2], cube[3][1][2], cube[3][0][2]]
        cube[3][0][2], cube[3][1][2], cube[3][2][2] = cube[1][0]
        cube[1][0] = [cube[4][2][0], cube[4][1][0], cube[4][0][0]]
        cube[4][0][0], cube[4][1][0], cube[4][2][0] = temp
        moveDimension(cube,0)
        
    elif direction == 'B': 
        temp = cube[2][0]
        cube[2][0] = [cube[4][0][2], cube[4][1][2], cube[4][2][2]]
        cube[4][2][2], cube[4][1][2], cube[4][0][2] = cube[1][2]
        cube[1][2] = [cube[3][0][0], cube[3][1][0], cube[3][2][0]]
        cube[3][2][0], cube[3][1][0], cube[3][0][0] = temp
        moveDimension(cube,5)    
        
    elif direction == 'L': 
        temp = [cube[0][0][0], cube[0][1][0], cube[0][2][0]]
        cube[0][0][0], cube[0][1][0], cube[0][2][0] = cube[2][0][0], cube[2][1][0], cube[2][2][0]
        cube[2][0][0], cube[2][1][0], cube[2][2][0] = cube[5][2][2], cube[5][1][2], cube[5][0][2]
        cube[5][0][2], cube[5][1][2], cube[5][2][2] = cube[1][2][0], cube[1][1][0], cube[1][0][0]
        cube[1][0][0], cube[1][1][0], cube[1][2][0] = temp
        moveDimension(cube,3)
        
    elif direction == 'R': 
        temp = [cube[0][0][2], cube[0][1][2], cube[0][2][2]]
        cube[0][0][2], cube[0][1][2], cube[0][2][2] = cube[1][0][2], cube[1][1][2], cube[1][2][2]
        cube[1][0][2], cube[1][1][2], cube[1][2][2] = cube[5][2][0], cube[5][1][0], cube[5][0][0]
        cube[5][0][0], cube[5][1][0], cube[5][2][0] = cube[2][2][2], cube[2][1][2], cube[2][0][2]
        cube[2][0][2], cube[2][1][2], cube[2][2][2] = temp
        moveDimension(cube,4) 
        
def go(cube,comm):
    direction, count = comm
    count = 1 if count == '+' else 3
    for _ in range(count): move(cube,direction)


for _ in range(int(input())):
    input(); comm = list(map(str, input().split()))
    cube = [[] for _ in range(6)]
    for _ in range(3):
        cube[0].append(['r','r','r']); cube[1].append(['y','y','y']); cube[2].append(['w','w','w'])
        cube[3].append(['g','g','g']); cube[4].append(['b','b','b']); cube[5].append(['o','o','o'])
    while comm: 
        go(cube,comm.pop(0))
    printResult(cube)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘</category>
      <category>5373</category>
      <category>Boi</category>
      <category>백준</category>
      <category>삼성 SW 역량 테스트</category>
      <category>알고리즘</category>
      <category>큐빙</category>
      <category>파이썬</category>
      <author>cra4ckerjack</author>
      <guid isPermaLink="true">https://crackerjacks.tistory.com/19</guid>
      <comments>https://crackerjacks.tistory.com/19#entry19comment</comments>
      <pubDate>Tue, 14 Jul 2020 11:13:37 +0900</pubDate>
    </item>
    <item>
      <title>알고리즘 풀이 백준(BOI) 17825) 주사위 윷놀이 (Python)</title>
      <link>https://crackerjacks.tistory.com/18</link>
      <description>&lt;h2 style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;백준(BOI) 17825 - 주사위 윷놀이&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr style=&quot;border: none; font-size: 0px; line-height: 0; height: 20px; margin: 20px auto; background: url('https://t1.daumcdn.net/keditor/dist/0.4.0/image/divider-line.svg') 0px -160px / 200px 200px no-repeat #ffffff; cursor: pointer !important; width: 200px; color: #666666; font-family: 'Noto Sans', sans-serif; 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; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1593677045187&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;17825번: 주사위 윷놀이&quot; data-og-description=&quot;주사위 윷놀이는 다음과 같은 게임판에서 하는 게임이다. 처음에는 시작 칸에 말 4개가 있다. 말은 게임판에 그려진 화살표의 방향대로만 이동할 수 있다. 말이 파란색 칸에서 이동을 시작하면 �&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/17825&quot; data-og-url=&quot;https://www.acmicpc.net/problem/17825&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dn0wji/hyGBR9BFY6/OXCfx8dabqYr7Cg7Z92BM1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/h5Ujz/hyGBQbNQVt/b5LUcxWlwgVjq4QOKuhtX0/img.png?width=1279&amp;amp;height=1170&amp;amp;face=0_0_1279_1170&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/17825&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/17825&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dn0wji/hyGBR9BFY6/OXCfx8dabqYr7Cg7Z92BM1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/h5Ujz/hyGBQbNQVt/b5LUcxWlwgVjq4QOKuhtX0/img.png?width=1279&amp;amp;height=1170&amp;amp;face=0_0_1279_1170');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;17825번: 주사위 윷놀이&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;주사위 윷놀이는 다음과 같은 게임판에서 하는 게임이다. 처음에는 시작 칸에 말 4개가 있다. 말은 게임판에 그려진 화살표의 방향대로만 이동할 수 있다. 말이 파란색 칸에서 이동을 시작하면 �&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;[ 문제풀이 ]&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;주사위를 굴려 나온 숫자만큼 윷놀이 말을 움직여 가면서 발판에 있는 점수들을 더해 얻을 수 있는 점수의 최대값을 출력하는 문제이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;문제에 대한 이해는 그림으로 보는 게 빠르다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&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/bDr74j/btqFkU0a4kG/aIsyBC9Hg7jpeRfOMSQvyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDr74j/btqFkU0a4kG/aIsyBC9Hg7jpeRfOMSQvyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDr74j/btqFkU0a4kG/aIsyBC9Hg7jpeRfOMSQvyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDr74j%2FbtqFkU0a4kG%2FaIsyBC9Hg7jpeRfOMSQvyK%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 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;&quot;말이 이동을 마치는 칸에 다른 말이 있으면 그 말은 고를 수 없다. 단, 이동을 마치는 칸이 도착 칸이면 고를 수 있다.&quot; 부분에서 해석이 갈릴 여지가 있는데, 말이 움직였을 때 도달하는 발판에 다른 말이 있으면 그냥 그 케이스는 제외하라는 말이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;필자는 처음에 윷놀이판을 &lt;span style=&quot;color: #ee2323;&quot;&gt;배열에 구현하려다 엄청나게 애먹었다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;결론부터 말하자면 이 문제는 딕셔너리( 키 : 벨류 로 이루어지는 자료형) 로 만드는 것이 가장 쉽다. 처음에 배열로 이 문제를 풀 때는 몇 번의 시행착오를 겪은 후에야 통과했지만 나중에 딕셔너리로 풀 때에는 아주 쉽게 통과했다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;혹시나 도움이 될 수 있기에 이번 포스팅에서는 필자가 풀었던 두 가지 방법 모두를 소개하려 한다. 참고로, 두 가지 방법 모두 DFS로 풀었다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;text-align: justify;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #456771;&quot;&gt;1. 윷놀이판을 배열로 구현하였을 경우&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;필자가 처음에 풀었던 방식으로, 윷놀이판을 2차원 배열에 담았다. 윷놀이판 같은 경우는 크게 외곽으로 쭉 빨간 선을 갈 경우, 맨 처음 파란선을 거쳐가는 경우, 두 번째 파란선을 거쳐 가는 경우, 세 번째 파란선을 거쳐 가는 경우 네 가지로 구분했다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1593679599843&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;grid = []
grid.append([0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40])
grid.append([0,13,16,19,25,30,35,40])
grid.append([0,22,24,25,30,35,40])
grid.append([0,28,27,26,25,30,35,40])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;이후 각 말들의 위치를 저장하기 위해 다음과 같이 선언해준다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593679659849&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;horseState = [(0,0),(0,0),(0,0),(0,0)]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;초기 상태에선 어떤 말을 움직여도 결과가 같으므로 첫 번째 말을 DFS에 담아 보내주었다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593679736417&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def go(horse, count, horseState, result):
&quot;&quot;&quot;
.
생략
.
&quot;&quot;&quot;


go(0,0,horseState,0)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;DFS에 들어오면 먼저 horseState를 깊은복사해준다. 깊은복사의 경우 원본 배열이 바뀌게 되면 완전탐색의 의미가 없어지기 때문이다. deepcopy가 너무 느릴까봐 일일이 복사해줬다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;이후 매개변수로 넘어온 말을 주사위대로 움직여준다. 윷놀이판을 배열로 구현하였으므로 갈림길(파란부분)에 서게 되면 다른 루트(다른 배열)로 넘겨주는 처리를 해줘야한다. 이는 move() 메소드에 구현하였다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593680018417&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def move(horseState, dice):
    global grid
    nowx, nowy = horseState
    if nowx == 0:
        nextx = 0
        if nowy == 5: nextx = 1; nowy = 0
        elif nowy == 10 : nextx = 2; nowy = 0
        elif nowy == 15 : nextx = 3; nowy = 0
    else: nextx = nowx
    return nextx, nowy + dice if nowy + dice &amp;lt; len(grid[nextx]) else -1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;nowx 는 grid의 첫번째 인덱스 (즉, 경로들) 을 의미한다. 첫 번째 경로 ( nowx == 0 ) 일 경우 발판의 5, 10, 15번째 인덱스에 위치하면 다른 경로로 이동하게 된다. 배열 범위를 넘어버리는 것은 도착을 의미한다. y값에 -1을 반환해주었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이후 말의 위치를 저장해놓는 배열을 깊은복사해놓은 copyState에서 위 말의 움직임을 반영해주고, 도착하지 않았을 경우 (즉, 점수가 있는 발판에 도달한 경우) 점수도 반영해준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1593680192306&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    copyState[horse] = (rx, ry)
    if ry != -1: result += grid[rx][ry]
    if count == 9: answer = max(answer, result); return&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;카운트가 9가 되었다는 것은 다음 주사위가 존재하지 않는다는 의미다. 때문에 점수만 반영해주고 종료해야한다. 최대값을 구하는 문제이므로 answer에는 항상 최대값만 저장시킨다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이후 DFS를 계속 실행하기 위해 go() 메소드를 재귀해야한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;u&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;여기서 필자의 경우 윷놀이판을 배열에 구현해서 큰 난관에 부딛혔다.&amp;nbsp;&lt;/span&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;문제에서 보면 도달하는 발판에 다른 말이 있을경우 해당 케이스는 넘겨야 한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;&quot;&gt;이는 적절한 조건을 주어서 for문에서 continue만 잘 주면 해결되는 문제이다. 하지만 구현해놓은 윷놀이판 배열을 다시 보자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1593680491105&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;grid.append([0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40])
grid.append([0,13,16,19,25,30,35,40])
grid.append([0,22,24,25,30,35,40])
grid.append([0,28,27,26,25,30,35,40])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;grid의 인덱스는 윷놀이판의 점수(발판)를 의미한다. 즉 인덱스는 현재 위치고 값은 점수이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;만약, 첫 번째 말이 지름길을 통하지 않고 4-5-5-5-1 를 거치면 40에 도달하게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;그런데, 두 번째 말이 5-5-2를 거치면 어떻게 될까? 첫 번째 지름길을 거쳐 40에 도달하게 된다. 로직대로라면 두 번째 말은 첫 번째 말이 이미 40에 위치하기 때문에 마지막 2를 수행할 수 없다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이같은 경우는 40 뿐만이 아니라 grid의 1~3&amp;nbsp; (지름길을 타는 경로)의 25, 30, 35, 40 도 마찬가지다. 이 발판에 위치하는 경우 다른 경로에도 말이 있는지 확인해줘야 한다. 딕셔너리로 윷놀이판을 구현할 경우에는 해당 키(발판)만 참조하면 되므로 이런 애로사항이 없다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;아무튼, 재귀는 다음과 같이 구현했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1593681213695&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    for i in range(4):
        oper = True
        if copyState[i][1] == -1: continue
        nx, ny = move(copyState[i], inputList[count+1])
        if ny != -1 and (nx, ny) in copyState: continue
        for ix,iy in copyState:
            if nx == 0 and ny == 20:
                if ((ix == 1 or ix == 3) and iy == 7) or (ix == 2 and iy == 6): oper = False; break
            elif nx == 1:
                if ny == 4:
                    if (ix == 3 and iy == 4) or (ix == 2 and iy == 3): oper = False; break
                elif ny == 5:
                    if (ix == 3 and iy == 5) or (ix == 2 and iy == 4): oper = False; break
                elif ny == 6:
                    if (ix == 3 and iy == 6) or (ix == 2 and iy == 5): oper = False; break 
                elif ny == 7:
                    if (ix == 3 and iy == 7) or (ix == 2 and iy == 6) or (ix == 0 and iy == 20): oper = False; break 
            elif nx == 2:
                if ny == 3:
                    if (ix == 1 or ix == 3) and iy == 4: oper = False; break
                elif ny == 4:
                    if (ix == 1 or ix == 3) and iy == 5: oper = False; break
                elif ny == 5:
                    if (ix == 1 or ix == 3) and iy == 6: oper = False; break
                elif ny == 6:
                    if ((ix == 1 or ix == 3) and iy == 7) or (ix == 0 and iy == 20) : oper = False; break
            elif nx == 3:
                if ny == 4:
                    if (ix == 1 and iy == 4) or (ix == 2 and iy == 3): oper = False; break
                elif ny == 5:
                    if (ix == 1 and iy == 5) or (ix == 2 and iy == 4): oper = False; break
                elif ny == 6:
                    if (ix == 1 and iy == 6) or (ix == 2 and iy == 5): oper = False; break 
                elif ny == 7:
                    if (ix == 1 and iy == 7) or (ix == 2 and iy == 6) or (ix == 0 and iy == 20): oper = False; break                
        
        if oper: go(i, count+1, copyState, result)    &lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-size=&quot;size18&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #456771;&quot;&gt;2. 윷놀이판을 딕셔너리로 구현하였을 경우&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;딕셔너리로 구현할 경우 말을 이동시킬 때 키만 참조하면 되므로 위와 같은 애로사항이 없다. 먼저 인덱스로 말판을 정해주고 각 인덱스에 대한 점수를 윷놀이판을 반영해 구현해주면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1593681830896&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gridDict = {
 0:[1,2,3,4,5],
 1:[2,3,4,5,6],
 2:[3,4,5,6,7],
 3:[4,5,6,7,8],
 4:[5,6,7,8,9],
 5:[21,22,23,24,25],
 6:[7,8,9,10,11],
 7:[8,9,10,11,12],
 8:[9,10,11,12,13],
 9:[10,11,12,13,14],
 10:[27,28,24,25,26],
 11:[12,13,14,15,16],
 12:[13,14,15,16,17],
 13:[14,15,16,17,18],
 14:[15,16,17,18,19],
 15:[29,30,31,24,25],
 16:[17,18,19,20,-1],
 17:[18,19,20,-1,-1],
 18:[19,20,-1,-1,-1],
 19:[20,-1,-1,-1,-1],
 20:[-1,-1,-1,-1,-1],
 21:[22,23,24,25,26],
 22:[23,24,25,26,20],
 23:[24,25,26,20,-1],
 24:[25,26,20,-1,-1],
 25:[26,20,-1,-1,-1],
 26:[20,-1,-1,-1,-1],
 27:[28,24,25,26,20],
 28:[24,25,26,20,-1],
 29:[30,31,24,25,26],
 30:[31,24,25,26,20],
 31:[24,25,26,20,-1]
}
scoreDict = {
    -1: 0, 0: 0, 1: 2, 2: 4, 3: 6, 4: 8, 5: 10, 6: 12, 7: 14, 8: 16, 9: 18, 10: 20,
    11: 22, 12:24, 13:26, 14:28, 15:30, 16:32, 17:34, 18:36, 19:38, 20:40, 21: 13, 22: 16,
    23: 19, 24: 25, 25: 30, 26: 35, 27: 22, 28: 24, 29: 28, 30: 27, 31: 26
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;gridDict는 인덱스로 구현한 발판의 위치로, 주사위로 갈 수 있는 다음 발판을 각 각 적어놓은 것이다. -1은 도착이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;scoreDict는 해당 인덱스에 대한 점수를 적어놓은 것이다. 이를 분리해놓은 이유는 30을 가진 발판이 2개 있 듯, 중복되있는 발판이 있기 때문이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;&quot;&gt;말의 위치는 state라는 1차원 배열에 저장해준다. 해당 배열에는 위 gridDict의 키값을 저장하는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593681990520&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;state = [0,0,0,0]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;딕셔너리로 구현하면 재귀 역시 쉬워진다. 그냥 키만 확인하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593681998814&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def go(horse, count, result, state):
    global gridDict, scoreDict, answer, inputArr
    copyState = state.copy()
    nowDice = inputArr[count] - 1
    copyState[horse] = gridDict[copyState[horse]][nowDice]
    nowScore = scoreDict[copyState[horse]]
    
    if count == 9 : answer = max(answer, result + nowScore); return

    nextDice = inputArr[count+1] - 1
    for i in range(4):
        if copyState[i] == -1: continue
        if gridDict[copyState[i]][nextDice] != -1 and gridDict[copyState[i]][nextDice] in copyState: continue
        
        go(i, count+1, result + nowScore, copyState)&lt;/code&gt;&lt;/pre&gt;
&lt;hr style=&quot;margin: 20px auto 0px; border: none; cursor: pointer !important; z-index: 1; font-size: 0px; line-height: 0; background: url('../image/divider-line.svg') center -362px / 200px 420px no-repeat; width: 200px; height: 19px; padding: 18px 20px 17px; color: #333333; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; 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; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;[ 전체 소스코드 ]&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&amp;nbsp;- 배열로 구현한 코드&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593676991429&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import copy

def move(horseState, dice):
    global grid
    nowx, nowy = horseState
    if nowx == 0:
        nextx = 0
        if nowy == 5: nextx = 1; nowy = 0
        elif nowy == 10 : nextx = 2; nowy = 0
        elif nowy == 15 : nextx = 3; nowy = 0
    else: nextx = nowx
    return nextx, nowy + dice if nowy + dice &amp;lt; len(grid[nextx]) else -1


def go(horse, count, horseState, result):
    global grid, inputList, answer
    # deep copy
    copyState = [(0,0) for _ in range(4)]
    for i in range(4):
        copyState[i] = horseState[i]    
    rx, ry = move(copyState[horse], inputList[count])
    copyState[horse] = (rx, ry)
    if ry != -1: result += grid[rx][ry]
    if count == 9: answer = max(answer, result); return
    
    for i in range(4):
        oper = True
        if copyState[i][1] == -1: continue
        nx, ny = move(copyState[i], inputList[count+1])
        if ny != -1 and (nx, ny) in copyState: continue
        for ix,iy in copyState:
            if nx == 0 and ny == 20:
                if ((ix == 1 or ix == 3) and iy == 7) or (ix == 2 and iy == 6): oper = False; break
            elif nx == 1:
                if ny == 4:
                    if (ix == 3 and iy == 4) or (ix == 2 and iy == 3): oper = False; break
                elif ny == 5:
                    if (ix == 3 and iy == 5) or (ix == 2 and iy == 4): oper = False; break
                elif ny == 6:
                    if (ix == 3 and iy == 6) or (ix == 2 and iy == 5): oper = False; break 
                elif ny == 7:
                    if (ix == 3 and iy == 7) or (ix == 2 and iy == 6) or (ix == 0 and iy == 20): oper = False; break 
            elif nx == 2:
                if ny == 3:
                    if (ix == 1 or ix == 3) and iy == 4: oper = False; break
                elif ny == 4:
                    if (ix == 1 or ix == 3) and iy == 5: oper = False; break
                elif ny == 5:
                    if (ix == 1 or ix == 3) and iy == 6: oper = False; break
                elif ny == 6:
                    if ((ix == 1 or ix == 3) and iy == 7) or (ix == 0 and iy == 20) : oper = False; break
            elif nx == 3:
                if ny == 4:
                    if (ix == 1 and iy == 4) or (ix == 2 and iy == 3): oper = False; break
                elif ny == 5:
                    if (ix == 1 and iy == 5) or (ix == 2 and iy == 4): oper = False; break
                elif ny == 6:
                    if (ix == 1 and iy == 6) or (ix == 2 and iy == 5): oper = False; break 
                elif ny == 7:
                    if (ix == 1 and iy == 7) or (ix == 2 and iy == 6) or (ix == 0 and iy == 20): oper = False; break                
        
        if oper: go(i, count+1, copyState, result)    
            
    

inputList = list(map(int, input().split()))
grid = []; answer = 0
grid.append([0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40])
grid.append([0,13,16,19,25,30,35,40])
grid.append([0,22,24,25,30,35,40])
grid.append([0,28,27,26,25,30,35,40])
horseState = [(0,0),(0,0),(0,0),(0,0)]
go(0,0,horseState,0)
print(answer)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&amp;nbsp;- 딕셔너리로 구현한 코드&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593682026870&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def go(horse, count, result, state):
    global gridDict, scoreDict, answer, inputArr
    copyState = state.copy()
    nowDice = inputArr[count] - 1
    copyState[horse] = gridDict[copyState[horse]][nowDice]
    nowScore = scoreDict[copyState[horse]]
    
    if count == 9 : answer = max(answer, result + nowScore); return

    nextDice = inputArr[count+1] - 1
    for i in range(4):
        if copyState[i] == -1: continue
        if gridDict[copyState[i]][nextDice] != -1 and gridDict[copyState[i]][nextDice] in copyState: continue
        
        go(i, count+1, result + nowScore, copyState)
    

inputArr = list(map(int, input().split()))
gridDict = {
 0:[1,2,3,4,5],
 1:[2,3,4,5,6],
 2:[3,4,5,6,7],
 3:[4,5,6,7,8],
 4:[5,6,7,8,9],
 5:[21,22,23,24,25],
 6:[7,8,9,10,11],
 7:[8,9,10,11,12],
 8:[9,10,11,12,13],
 9:[10,11,12,13,14],
 10:[27,28,24,25,26],
 11:[12,13,14,15,16],
 12:[13,14,15,16,17],
 13:[14,15,16,17,18],
 14:[15,16,17,18,19],
 15:[29,30,31,24,25],
 16:[17,18,19,20,-1],
 17:[18,19,20,-1,-1],
 18:[19,20,-1,-1,-1],
 19:[20,-1,-1,-1,-1],
 20:[-1,-1,-1,-1,-1],
 21:[22,23,24,25,26],
 22:[23,24,25,26,20],
 23:[24,25,26,20,-1],
 24:[25,26,20,-1,-1],
 25:[26,20,-1,-1,-1],
 26:[20,-1,-1,-1,-1],
 27:[28,24,25,26,20],
 28:[24,25,26,20,-1],
 29:[30,31,24,25,26],
 30:[31,24,25,26,20],
 31:[24,25,26,20,-1]
}
scoreDict = {
    -1: 0, 0: 0, 1: 2, 2: 4, 3: 6, 4: 8, 5: 10, 6: 12, 7: 14, 8: 16, 9: 18, 10: 20,
    11: 22, 12:24, 13:26, 14:28, 15:30, 16:32, 17:34, 18:36, 19:38, 20:40, 21: 13, 22: 16,
    23: 19, 24: 25, 25: 30, 26: 35, 27: 22, 28: 24, 29: 28, 30: 27, 31: 26
}
answer = 0
state = [0,0,0,0]
go(0,0,0,state)
print(answer)&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘</category>
      <category>17825</category>
      <category>Boi</category>
      <category>백준</category>
      <category>삼성 SW 역량 테스트</category>
      <category>알고리즘</category>
      <category>주사위 윷놀이</category>
      <category>파이썬</category>
      <author>cra4ckerjack</author>
      <guid isPermaLink="true">https://crackerjacks.tistory.com/18</guid>
      <comments>https://crackerjacks.tistory.com/18#entry18comment</comments>
      <pubDate>Thu, 2 Jul 2020 18:28:09 +0900</pubDate>
    </item>
    <item>
      <title>알고리즘 풀이 백준(BOI) 17822) 원판 돌리기 (Python)</title>
      <link>https://crackerjacks.tistory.com/17</link>
      <description>&lt;h2 style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;백준(BOI) 17822 - 원판 돌리기&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr style=&quot;border: none; font-size: 0px; line-height: 0; height: 20px; margin: 20px auto; background: url('https://t1.daumcdn.net/keditor/dist/0.4.0/image/divider-line.svg') 0px -160px / 200px 200px no-repeat #ffffff; cursor: pointer !important; width: 200px; color: #666666; font-family: 'Noto Sans', sans-serif; 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; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1593578741928&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;17822번: 원판 돌리기&quot; data-og-description=&quot;반지름이 1, 2, ..., N인 원판이 크기가 작아지는 순으로 바닥에 놓여있고, 원판의 중심은 모두 같다. 원판의 반지름이 i이면, 그 원판을 i번째 원판이라고 한다. 각각의 원판에는 M개의 정수가 적혀&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/17822&quot; data-og-url=&quot;https://www.acmicpc.net/problem/17822&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/NXnbC/hyGBRAQLHV/f6jLOrIJ4p681rbQFBOzTk/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/17822&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/17822&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/NXnbC/hyGBRAQLHV/f6jLOrIJ4p681rbQFBOzTk/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;&gt;17822번: 원판 돌리기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;반지름이 1, 2, ..., N인 원판이 크기가 작아지는 순으로 바닥에 놓여있고, 원판의 중심은 모두 같다. 원판의 반지름이 i이면, 그 원판을 i번째 원판이라고 한다. 각각의 원판에는 M개의 정수가 적혀&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;[ 문제풀이 ]&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: justify;&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp; 숫자가 적혀있는 원판을 지시대로 돌리면서 어떤 숫자와 인접한 숫자가 존재할 경우 그 숫자는 지워준다. 인접하는 두 개 이상의 숫자가 하나라도 존재하지 않을 경우 판에 남아있는 숫자들의 평균값을 구해 평균보다 작은 숫자엔 +1을 큰 숫자엔 -1을 한다. 이후 판을 모두 돌리고 난 후의 판에 남아있는 숫자들을 전부 더해 결과를 출력하는 문제이다&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;이 문제는 배열의 회전과 인접한 숫자들의 체크만 잘해주면 별 무리 없이 통과할 수 있는 문제이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;필자는 78% 부근에서 런타임 에러를 겪었는데 함정이 하나 존재한다.(&lt;s&gt;사실 생각해보면 함정도 아니다&lt;/s&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;메모리와 시간이 여유 있게 주어지므로 지시하는 대로 구현만 잘해주면 된다. 특수한 기법이나 기똥찬 방법을 쓰지는 않았다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;먼저 문제에서 주어진 로직은 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #456771;&quot;&gt;&lt;b&gt;&lt;span style=&quot;&quot;&gt;1. 원판을 회전시킨다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;&quot;&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;span style=&quot;&quot;&gt;&amp;nbsp;입력으로 x, d, k가 주어진다. x의 배수에 해당되는 원판 전부를 모두 k번만큼 d(0 : 시계, 1 : 반시계) 방향으로 회전시키면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;&quot;&gt;&amp;nbsp;필자는 원판을 2차원 배열로 받았고 시계방 향일 경우 0번 인덱스를 temp 변수에 저장해놓고 4번 인덱스부터 3번 인덱스를 4번 인덱스에 복사하는 방식으로 구현했다. (반시계 방향은 마지막 인덱스를 저장해놓고 방향만 반대로)&lt;/span&gt;&lt;span style=&quot;&quot;&gt;rotate() 메소드가 이를 구현한 코드다, targetList는 rotate()를 호출하기 전 x의 배수를 구해주는 calcTarget() 함수의 결과로 받은 배열이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #456771;&quot;&gt;&lt;b&gt;&lt;span style=&quot;&quot;&gt;2. 회전이 완료된 원판에서 인접한 숫자가 있는지 체크한다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;span style=&quot;&quot;&gt;&amp;nbsp;checkGrid() 메소드에 구현하였으며, 그리드의 모든 부분을 대상으로 값이 -1이 아닐 경우 좌표를 매개변수로 하여 해당 함수를 호출한다.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;&quot;&gt;&amp;nbsp;해당 함수에서는 받은 좌표값을 큐에 넣어주고 이후 방향을 탐색하면 된다. 필자는 원판을 2차원 배열에 구현하였으니 이에 주의하여 탐색을 하여야 한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;&quot;&gt;&amp;nbsp;다음은 2차원 배열에 원판을 구현하였을 경우 필자가 주의한 사항이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;&quot;&gt;열(칼럼)을 이동할 때에는 끝과 처음으로 이동이 가능하다. &lt;/span&gt;&lt;span style=&quot;&quot;&gt;즉 인덱스가 len(grid[i]) 에 도달하면 이는 0으로, 인덱스가 음수에 도달하면 이는 len(grid[i])-1 로 치환해주어야 한다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;&quot;&gt;행(로우)은 처음과 끝의 이동이 불가능하다.&amp;nbsp; 4번 판에서 1번 판의 비교는 당연히 할 수 없다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;&quot;&gt;어떤 인덱스의 전후좌우만 체크하는 게 아니라 인접한 수가 있으면 그 수의 전후좌우도 체크해 줘야 한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이 외에는 일반적으로 탐색하듯이 탐색하면 된다. 필자는 큐를 돌릴 때 인접한 수가 있는 경우에만 원본 좌표와 인접 좌표를 그리드에서 -1로 바꾸는 식으로 탐색했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-size=&quot;size18&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #456771;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;3. 위 (2.)를 만족하는 경우가 하나라도 없으면 평균값을 구해서 연산을 실시한다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;인접하는 숫자가 없어 지워지는 숫자가 하나라도 없을 경우 calcAvg()를 호출한다. 먼저 판의 평균값을 구한다. 이후 판에 남아있는 모든 숫자에 대해서 숫자 &amp;gt; 평균값이라면 숫자에 -1을, 숫자 &amp;lt; 평균값이라면 숫자에 +1을 해준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;이 로직에서 함정이 두 개 존재한다. (&lt;s&gt;사실 꼼꼼하다면 함정도 아니다&lt;/s&gt;)&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;먼저, 평균값은 정수가 아닌 실수형이다. 문제를 꼼꼼히 보았다면 예시에서 이미 확인했겠지만, 다음을 한번 보자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&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/SvxpW/btqFgINg3kk/lVABJT3vtAjN8C9jaK1Lyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SvxpW/btqFgINg3kk/lVABJT3vtAjN8C9jaK1Lyk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SvxpW/btqFgINg3kk/lVABJT3vtAjN8C9jaK1Lyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSvxpW%2FbtqFgINg3kk%2FlVABJT3vtAjN8C9jaK1Lyk%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 data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;왼쪽 판은 회전을 마친 판이고 오른쪽 판은 인접한 수가 없어 평균값 구해 연산을 해준 결과이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;여기서 평균은 22/6 이므로 정수 값은 3이다. 한데 오른쪽 판을 보면 왼쪽 판의 첫 번째 판의 9시 부근에 있던 3이 4로 바뀐 것을 확인할 수 있다. (4는 3으로 바뀐 것도 확인할 수 있다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;&quot;&gt;&amp;nbsp;문제에서는 그냥 평균값으로 주어져 있는 데다가, 예제를 꼼꼼히 보지 않고서는 습관적으로 정수로 형 변환을 하는 필자 같은 경우라면 이 함정에서 한번 넘어지게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;다음 함정은 다음과 같은 케이스이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593580555031&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# input&amp;gt;&amp;gt;
3 3 3
1 1 1
1 1 1
1 1 1
1 0 1
2 0 1
3 0 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;70% 넘은 부분에서 런타임 에러를 겪었다면 위 테스트 케이스를 통과하지 못한 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;위 테스트 케이스는 세 번 원판을 돌리지만 초기 단계가 모두 1로 같은 숫자이다. 때문에 첫 번째 회전에서 판에 있는 모든 숫자가 지워지게 된다. 여기서 두 번째 회전에서는 더 이상 지워진 값이 없기 때문에 필자의 로직대로라면 평균값을 계산해야 한다. 필자는 평균값의 계산을 판 전체를 탐색하면서 숫자가 존재하는 경우 count를 +=1 해주고 숫자를 더해두었다가 그 더해진 숫자를 count로 나눠진 방식으로 구현했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;하지만 판에 아무런 숫자도 존재하지 않는데 평균을 계산하는 메소드에 들어오면 count는 0이 되어 대표적인 런타임 에러 '0으로 나눌 수 없습니다'를 겪게 되는 것이다. 필자는 count로 나누기 전 count가 0이면 리턴해주는 줄을 추가하여 통과하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-size=&quot;size18&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #456771;&quot;&gt;&lt;b&gt;&lt;span style=&quot;&quot;&gt;4. k 횟수만큼 이를 반복하다가 마지막에 남아있는 숫자의 총합을 출력한다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;span style=&quot;&quot;&gt;&amp;nbsp;calcResult() 함수에서 그리드에 -1이 아닌 경우 숫자를 더해 반환해주며 이를 출력해준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;한 번의 런타임 에러를 겪은 후 통과하였고, 시간 초과와 메모리 초과 또한 겪지 않았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr style=&quot;margin: 20px auto 0px; border: none; cursor: pointer !important; z-index: 1; font-size: 0px; line-height: 0; background: url('../image/divider-line.svg') center -362px / 200px 420px no-repeat; width: 200px; height: 19px; padding: 18px 20px 17px; color: #333333; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; 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; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;[전체 소스코드]&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1593580955247&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def calcResult():
    global grid
    answer = 0
    for i in range(len(grid)):
        for j in range(len(grid[i])):
            if grid[i][j] != -1:
                answer += grid[i][j]  
    return answer

def calcTarget(x):
    global n
    resultList = []
    for i in range(1, n+1):
        if i % x == 0 : resultList.append(i-1)
    return resultList

def checkGrid(i,j):
    global grid
    result = 0
    directions = (1, 0), (-1, 0), (0, 1), (0, -1)
    qu = []
    qu.append([i,j])
    num = grid[i][j]
    while qu:
        nowx, nowy = qu.pop(0)        
        for dx, dy in directions:
            nextx = nowx + dx; nexty = nowy + dy;
            if nextx &amp;lt; 0 or nextx &amp;gt;= len(grid): continue
            if nexty == len(grid[i]): nexty = 0
            elif nexty &amp;lt; 0 : nexty = len(grid[0]) - 1
            if grid[nextx][nexty] == num:
                qu.append([nextx,nexty])
                grid[i][j] = -1
                grid[nextx][nexty] = -1
                result += 1
    return result
            
def calcAvg():
    global grid
    result = 0; count = 0;
    for i in range(len(grid)):
        for j in range(len(grid[i])):
            if grid[i][j] != -1:
                result += grid[i][j]; count += 1
    if count == 0 : return
    result = result / count
    for i in range(len(grid)):
        for j in range(len(grid[i])):
            if grid[i][j] != -1:
                if grid[i][j] &amp;gt; result: grid[i][j] -= 1
                elif grid[i][j] &amp;lt; result: grid[i][j] += 1

def rotate(targetList,d,k):
    global grid
    while k &amp;gt; 0:
        for target in targetList:
            if d == 1 : temp = grid[target][len(grid[target])-1]
            else: temp = grid[target][0]
            if d == 1 : 
                for j in range(len(grid[target])-1):
                    grid[target][len(grid[target])-1-j] = grid[target][len(grid[target])-1-j-1]
                grid[target][0] = temp
            else: 
                for j in range(len(grid[target])-1):
                    grid[target][j] = grid[target][j+1]
                grid[target][len(grid[target])-1] = temp
        k-=1
    result = 0
    for i in range(len(grid)):
        for j in range(len(grid[i])):
            if grid[i][j] != -1:
                result += checkGrid(i,j)
    if result == 0 : calcAvg()
         
def go(param):
    x,d,k = param
    targetList = calcTarget(x)
    rotate(targetList,1 if d == 0 else -1,k)
    
n, m, t = map(int, input().split())
grid = []
for _ in range(n):
    grid.append(list(map(int,input().split())))
qu = []
for _ in range(t):
    qu.append(list(map(int,input().split())))
while qu:
    go(qu.pop(0))

print(calcResult())&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘</category>
      <category>17822</category>
      <category>Boi</category>
      <category>백준</category>
      <category>삼성 SW 역량 테스트</category>
      <category>알고리즘</category>
      <category>원판 돌리기</category>
      <category>파이썬</category>
      <author>cra4ckerjack</author>
      <guid isPermaLink="true">https://crackerjacks.tistory.com/17</guid>
      <comments>https://crackerjacks.tistory.com/17#entry17comment</comments>
      <pubDate>Wed, 1 Jul 2020 14:24:27 +0900</pubDate>
    </item>
    <item>
      <title>알고리즘 풀이 백준(BOI) 17140) 이차원 배열과 연산 (Python)</title>
      <link>https://crackerjacks.tistory.com/16</link>
      <description>&lt;h2 style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;백준(BOI) 17140 - 이차원 배열과 연산&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr style=&quot;border: none; font-size: 0px; line-height: 0; height: 20px; margin: 20px auto; background: url('https://t1.daumcdn.net/keditor/dist/0.4.0/image/divider-line.svg') 0px -160px / 200px 200px no-repeat #ffffff; cursor: pointer !important; width: 200px; color: #666666; font-family: 'Noto Sans', sans-serif; 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; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&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;figure id=&quot;og_1593503963254&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;17140번: 이차원 배열과 연산&quot; data-og-description=&quot;첫째 줄에 r, c, k가 주어진다. (1 &amp;le; r, c, k &amp;le; 100) 둘째 줄부터 3개의 줄에 배열 A에 들어있는 수가 주어진다. 배열 A에 들어있는 수는 100보다 작거나 같은 자연수이다.&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/17140&quot; data-og-url=&quot;https://www.acmicpc.net/problem/17140&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/TeMjA/hyGAp59sdc/tMbwADHbLAYnpOogAzbKS1/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/17140&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/17140&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/TeMjA/hyGAp59sdc/tMbwADHbLAYnpOogAzbKS1/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;&gt;17140번: 이차원 배열과 연산&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;첫째 줄에 r, c, k가 주어진다. (1 &amp;le; r, c, k &amp;le; 100) 둘째 줄부터 3개의 줄에 배열 A에 들어있는 수가 주어진다. 배열 A에 들어있는 수는 100보다 작거나 같은 자연수이다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;[문제풀이]&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp; 3 * 3 배열을 입력받고 'R' 연산과 'C'연산을 계속 반복하여 테이블을 변형시키다가 원하는 인덱스에 원하는 숫자가 있을 경우 이때의 Count를 출력해주는 문제이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;R연산과 C연산은 대상을 테이블의 로우로 할 것인지 칼럼으로 할 것인지만 다르고 연산 방법은 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;연산 방법은 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;R연산 (행의 길이 &amp;gt;= 열의 길이) :&amp;nbsp;테이블 행 하나하나를 대상으로 실행한다.&amp;nbsp; 테이블의 첫 번째 행이 [1,3,2,1] 일 경우 1이 두 개, 2가 한 개, 3이 한 개 이므로 결과는 [2,1,3,1,1,2]이다. 정렬순서는 횟수의 오름차순을 우선으로 하고 동일 횟수일 경우 숫자의 오름차순으로 한다. 두 번째 행이 [1 2 1] 일 경우 [2 1 1 2]인데, 만약 여기서 연산이 종료된다면 테이블 각 행의 최고 길이는 6이므로 빈칸을 0으로 메운다. 즉 [2 1 1 2 0 0] 이 된다.C연산 (행의 길이 &amp;lt; 열의 길이) :&amp;nbsp;&amp;nbsp;R연산과 동일하지만 대상이 테이블의 열이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;위 연산을 반복하다 100의 길이를 넘어가면 나머지는 버린다. 이후 원하는 좌표에 원하는 값이 있을 경우 종료하고 카운트를 반환하는 문제이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이 문제는 배열의 정렬방법과 몇 가지만 주의하면 쉽게 풀 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;먼저 말하자면 필자는 틀리게 제출했는데 맞았다. 제출하던 중 배열의 길이가 100이 넘어가면 초과된 부분은 버리는 코드를 작성하지 않은 걸 깨달았는데 정답처리가 되었다. &lt;s&gt;테스트 케이스에 그런 경우가 존재하지 않는 것 같다.&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;위 연산은 딕셔너리를 이용했고 정렬은 람다식으로 했다. 딕셔너리를 이용한 이유는 1이 존재하면 거기에 밸류 값만 늘려주는 방식이 왠지 편할 것 같았다. &amp;nbsp;R연산을 예시로, 다음과 같이 구현했다. 딕셔너리를 초기화하고 행을 탐색한다. 행의 한 열 한 열에 대해 딕셔너리에 키가 존재하면 밸류에 +1을, 키가 존재하지 않으면 그 숫자에 대한 키:밸류 값을 만들어준다. (ex. 3 : 1) &lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593505571575&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dic = {}
&quot;&quot;&quot;
... 이하생략 ...
&quot;&quot;&quot;
if dic.get(item) is None:
	dic.update({item:1})
else:
	num = dic.get(item)
	num += 1
	dic.update({item:num})&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;이후 정렬을 해주면 문제에서 요구하는 배열과 똑같아진다. 정렬은 이중 정렬로 람다식을 사용했다. 정렬의 우선순위는 출현 횟수를 우선으로 오름차순으로, 동일할 경우 숫자를 오름차순으로 정렬해주는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593505681054&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;arr = sorted(dic.items(), key = lambda x: (x[1], x[0])) &lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;dic.items()는 딕셔너리를 배열 형태로 리턴해준다. 이 배열을 가지고 (키 = 람다식) 기준으로 정렬해준 후 arr에 대입한다. 람다식은 딕셔너리의 인덱스 1의 밸류 값(출현 횟수)을 1순위로, 인덱스 0의 밸류 값(숫자)을 2순위로 하여 정렬해준다. &lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;c.f) x[1] 앞에 -를 붙여주면 내림차순이 된다.&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;이후 배열을 반환하고 그 배열을 가지고 다시 R, C연산을 하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;문제를 풀다 주의해야할 함정이 하나 있다. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;예제 6에서 오류가 났으면 깨달았을 수도 있지만 다음과 같은 입력을 보자.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1593506011064&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;3 3 3
1 1 1
1 1 1
1 1 1&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;grid[2][2] == 3 이 오면 종료된다. 하지만 함정이다. 위 배열은 첫 번째 r연산을 거치면 3*2 배열이 된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593506106243&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 초기상태
[1 1 1]
[1 1 1]
[1 1 1]
# R연산 (r &amp;gt;= c)
[1 3]
[1 3]
[1 3]
# R연산 (r &amp;gt;= c)
[1 1 3 1]
[1 1 3 1]
[1 1 3 1]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;첫 번째 R연산을 거친 후 grid[2][2] 를 별다른 조건 없이 체크하게 되면 런타임 에러다. 주의하자.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이 문제는 로직이라 할 게 따로 없으니 정리하지 않겠다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr style=&quot;margin: 20px auto 0px; border: none; cursor: pointer !important; z-index: 1; font-size: 0px; line-height: 0; background: url('../image/divider-line.svg') center -362px / 200px 420px no-repeat; width: 200px; height: 19px; padding: 18px 20px 17px; color: #333333; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; 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; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;[전체 소스코드]&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1593504568164&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def go(indi):
    global grid
    arr = []; result = []
    dic = {}
    maxlength = 0
    #R연산
    if indi == 0:
        for i in range(len(grid)):
            dic.clear()
            arr.clear()
            for j in range(len(grid[i])):
                if grid[i][j] != 0:
                    arr.append(grid[i][j])
            for item in arr:
                if dic.get(item) is None:
                    dic.update({item:1})
                else:
                    num = dic.get(item)
                    num += 1
                    dic.update({item:num})
            arr.clear()
            arr = sorted(dic.items(), key = lambda x: (x[1], x[0])) 
            temp = []
            for item in arr:
                for item in item:
                    temp.append(item)
            result.append(temp)
            for item in result:
                maxlength = max(maxlength , len(item))
            returnArr = [[0 for _ in range(maxlength)]for _ in range(len(grid))]
            for i in range(len(result)):
                for j in range(len(returnArr[0])):
                    if j &amp;lt; len(result[i]):
                        returnArr[i][j] = result[i][j]            
    #C연산
    else:
        for i in range(len(grid[0])):
            dic.clear()
            arr.clear()
            for j in range(len(grid)):
                if grid[j][i] != 0:
                    arr.append(grid[j][i])
            for item in arr:
                if dic.get(item) is None:
                    dic.update({item:1})
                else:
                    num = dic.get(item)
                    num += 1
                    dic.update({item:num})
            arr.clear()
            arr = sorted(dic.items(), key = lambda x: (x[1], x[0])) 
            temp = []
            for item in arr:
                for item in item:
                    temp.append(item)
            result.append(temp)
            for item in result:
                maxlength = max(maxlength , len(item))        
            returnArr = [[0 for _ in range(len(grid[0]))]for _ in range(maxlength)]
            for i in range(len(result)):
                for j in range(len(returnArr)):
                    if j &amp;lt; len(result[i]):
                        returnArr[j][i] = result[i][j]                        
    return returnArr
    
r, c, k = map(int, input().split())
r-=1; c-=1
grid = [list(map(int, input().split())) for _ in range(3)]
answer = 0
while True:
    if r &amp;lt; len(grid) and c &amp;lt; len(grid[0]):
        if grid[r][c] == k : break
    answer += 1
    if answer &amp;gt; 100 : answer = -1; break
    if len(grid) &amp;gt;= len(grid[0]): grid = go(0)
    else: grid = go(1)
print(answer)

&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘</category>
      <category>17140</category>
      <category>Boi</category>
      <category>백준</category>
      <category>삼성 SW 역량 테스트</category>
      <category>알고리즘</category>
      <category>이차원 배열과 연산</category>
      <category>파이썬</category>
      <author>cra4ckerjack</author>
      <guid isPermaLink="true">https://crackerjacks.tistory.com/16</guid>
      <comments>https://crackerjacks.tistory.com/16#entry16comment</comments>
      <pubDate>Tue, 30 Jun 2020 17:41:26 +0900</pubDate>
    </item>
    <item>
      <title>SAP 혁신성장 청년인재 양성과정) ABAP 04) Internal Table</title>
      <link>https://crackerjacks.tistory.com/15</link>
      <description>&lt;h2 style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;04) Internal Table&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr style=&quot;border: none; font-size: 0px; line-height: 0; height: 20px; margin: 20px auto; background: url('https://t1.daumcdn.net/keditor/dist/0.4.0/image/divider-line.svg') 0px -160px / 200px 200px no-repeat #ffffff; cursor: pointer !important; width: 200px; color: #666666; font-family: 'Noto Sans', sans-serif; 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; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;i&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #9d9d9d;&quot;&gt;본 게시물은 SAP 혁신성장 청년인재 양성과정에서 교육받는 교육생이 정리 목적으로 포스팅하는 것으로,&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;i&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #9d9d9d;&quot;&gt;전문성 및 실용성이 다소 떨어지거나 정보가 부정확할 수 있으니&amp;nbsp;참고 목적으로만&amp;nbsp;읽어주시기 바랍니다.&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Internal Table&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;앞서 Data를 담을 수 있는 공간인 Data Object에 대해 이미 살펴본 바 있는데, 이번 포스팅에서는 Data Object 중 ABAP에서 가장 많이 쓰이고 핵심적이라 할 수 있는 Internal Table에 대해 살펴보려 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;먼저 데이터베이스 관점으로 '테이블'의 특징에 대해 차근차근 알아보자.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;대부분의 데이터(정보)는 2차원 형태의 테이블 구조에서 아주 쉽게 정의될 수 있다. 복잡한 내용도 가로 세로 일목요연하게 표(테이블)로 정리하면 데이터를 한눈에 보기 쉬워지고 내가 원하는 데이터도 쉽게 찾을 수도 있다. 이런 특징 때문에 대부분의 데이터는 열(칼럼)과 행(로우)으로 구성되는 2차원적인 테이블 구조를 가진다. 때문에, 우리는 저장되어있는 데이터를 다루기 위해 '테이블'을 도구로 사용할 수밖에 없는 것이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&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;760&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cyHZPA/btqFdKrapBI/tkPLNq87NlKnKH5aU6FMaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cyHZPA/btqFdKrapBI/tkPLNq87NlKnKH5aU6FMaK/img.png&quot; data-alt=&quot;아무개 대학교 어떤 수업의 &amp;amp;#39;학생&amp;amp;#39; 이라는 정보는 다음과 같이 2차원 구조인 표로 나타내면 정리가 아주 쉬워진다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cyHZPA/btqFdKrapBI/tkPLNq87NlKnKH5aU6FMaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcyHZPA%2FbtqFdKrapBI%2FtkPLNq87NlKnKH5aU6FMaK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;760&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;아무개 대학교 어떤 수업의 '학생' 이라는 정보는 다음과 같이 2차원 구조인 표로 나타내면 정리가 아주 쉬워진다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;테이블은 위와 같이 테이블을 구성하는 데이터의 속성(Attribute)을 열(컬럼)에 정의한다. 행(로우)은 학생 한 명 한 명으로 지정된 컬럼 데이터로 이루어진 하나의 묶음(Structure)라고 볼 수 있다. &amp;nbsp;이처럼 2차원 구조에 데이터를 성격에 맞게 분리해 가급적 중복되지 않게 저장하고 필요한 데이터는 테이블 간에 관계를 맺어 추출하는 것을 '관계형 데이터베이스'라고 한다. 관계형 데이터베이스는 요즘과 같이 변화무쌍한 시대에서 다양한 정보를 하나의 컬럼에 정의해 줄 수 없다는 단점이 있지만, 데이터를 정리하고 추출하기 쉽다는 장점이 워낙 강력해서 여전히 다양한 DB 프로그램에서 광범위하게 쓰인다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;위 테이블을 다시 살펴보자, '고길동' 씨를 찾고 싶을 땐 어떻게 하면 될까? '학생' 테이블의 2번째 인덱스를 참조하면 된다. 하지만 '고길동'이라는 이름을 가진 사람이 2명 이상이면 어떻게 해야 하는가?&amp;nbsp;이 같은 문제를 해결하고자 관계형 데이터베이스 관리 시스템(RDBMS)에서는 데이터 테이블에 반드시 하나의 키가 되는 컬럼을 두도록 권고하고 있다. 수많은 학생들은 서로 다른 고유의 번호 '학번'을 가지고 있다. unique 한 특징을 가진 '학번'이 바로 '키'가 되어 데이터의 정확성을 보장해주고 올바른 데이터를 유지하게 해주는 것이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;데이터베이스에는 다양한 키가 있지만, 개념적인 부분은 이것으로 충분할 것 같아 데이터베이스에 관한 설명은 여기까지만 다루겠다. 당장 '관계형 데이터베이스'로 구글링만 해도 정리가 아주 잘 된 정보가 넘쳐나니 공부가 더 필요하다면 여기보다는 그 글을 참고하는 게 날 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;ABAP에서는 무수히 많은 데이터를 다룬다. 고객사의 자재와 운송장, 제품에 대한 재고와 항공편의 내역까지 다양한 데이터가 데이터베이스에 저장되어 있다. 데이터베이스에 저장된 데이터를 끌어다 쓰거나, 데이터를 삽입/수정/삭제할 때 데이터베이스에 '요청'한다. 이를 '쿼리(Query) 문'이라고 한다. SQL(Structured Query Language)라고 불리는 쿼리문은 데이터베이스에 접근할 때 사용되는 언어이다. 테이블에 데이터를 저장하고 저장된 데이터를 테이블에 불러오고, 결국 데이터베이스는 쿼리가 전부이고 테이블은 이를 위한 '도구' 중 하나일 뿐이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;이번 포스팅에서는 SQL을 위한 도구인 '테이블'에만 집중하려 하기 때문에 SQL은 다음에 다루도록 하겠다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;테이블은 결국 데이터를 저장하고 읽기 위한 공간이다. 데이터를 저장하고 읽기 위한 방법은 다양한데, 이런 기능적인 측면에서 테이블의 종류를 살펴보자.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;Internal-1.jpg&quot; data-origin-width=&quot;633&quot; data-origin-height=&quot;413&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uw036/btqFdJZ5Byg/QQseYuxJ2LWE7GQEbeum90/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uw036/btqFdJZ5Byg/QQseYuxJ2LWE7GQEbeum90/img.jpg&quot; data-alt=&quot;출처 : https://sapforbeginner.wordpress.com/tag/hashed-table/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uw036/btqFdJZ5Byg/QQseYuxJ2LWE7GQEbeum90/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fuw036%2FbtqFdJZ5Byg%2FQQseYuxJ2LWE7GQEbeum90%2Fimg.jpg&quot; data-filename=&quot;Internal-1.jpg&quot; data-origin-width=&quot;633&quot; data-origin-height=&quot;413&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;출처 : https://sapforbeginner.wordpress.com/tag/hashed-table/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;테이블은 결국 데이터를 읽고 쓰는데 목적이 있으므로 효율적으로 데이터를 다루는 것이 무엇보다 중요하다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이러한 기능적인 측면에서 테이블은 위와 같이 구분할 수 있는데, 각 테이블마다 데이터에 접근하는 방법 및 속도가 다르다. 먼저 가장 많이 쓰이는 Standard Table에 대해 살펴보자.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Standard Table&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;가장 많이 쓰이는 일반적인 테이블이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;다음과 같이 선언해 줄 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593483738712&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;TYPES: BEGIN OF TY_STUDENTS,
ID(8)          TYPE N,
NAME(30) TYPE C,
END OF TY_STUDENTS.

DATA: LS_STUDENT TYPE TY_STUDENTS.

*Referring to local data type
DATA: LT_STUDENT_STD1 TYPE STANDARD TABLE OF TY_STUDENTS.

*Referring to local data object
DATA: LT_STUDENT_STD2 LIKE TABLE OF LS_STUDENT.

*Referring to data type in ABAP dictionary
DATA: LT_STUDENT_STD3 TYPE TABLE OF MARA.&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp; 순서대로 로컬 데이터 타입, 데이터 오브젝트(Structure) ABAP Dictionary에 있는 Global Data Object를 참조하여 정의하는 방법이다. 테이블을 정의할 때 별다른 옵션을 주지 않으면 기본적으로 Standard Table이 생성된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Standard Table은 내부적으로 로우의 넘버링(인덱스)이 유지되어 일반적으로 인덱스 값으로 데이터를 참조하는 특징을 가진다. (key를 통한 접근도 가능하다.)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;인덱스로 데이터를 참조하는 게 무슨 말인가 하면, 위 학생 테이블에서 '경제학과'의 '김길동'씨에 대한 정보를 찾아오려면 첫 번째 인덱스... 두 번째 인덱스 ... 를 지나 다섯 번째 인덱스에서 필요한 정보를 찾을 수 있다는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;인덱스로 데이터를 참조하면 $$O(n^2)$$의 시간 복잡도를 가진다. 즉, 컬럼 * 로우만큼 데이터를 탐색해야 하니 가장 느린 탐색 속도를 가지는 것이다. 하지만 인덱스만 알고 있으면 그 인덱스에 대한 데이터를 조회/수정 가능하니 조작 관점에서는 강점을 가진다. 속도는 느릴 수 있지만 직관적이고 강력한 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Sorted Table&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;문자 그대로 정렬된 테이블이다. 특정한 키를 지정해 주면 테이블 내부에서 자동적으로 정렬해준다. Standard Table에도 Sort 하는 방법이 있기 때문에 많이 사용하지는 않는다고 한다. 테이블을 선언할 때 Sorted옵션 값을 주어서 생성하고 정렬되는 기준인 Key를 꼭 지정해주어야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593484059424&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;TYPES: BEGIN OF TY_STUDENTS,
ID(8)          TYPE N,
NAME(30) TYPE C,
END OF TY_STUDENTS.*Referring to local data type
DATA: LT_STUDENT_SORT TYPE SORTED TABLE OF TY_STUDENTS WITH NON-UNIQUE KEY ID.&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;위와 같이 테이블을 선언해주면 ID를 기준으로 정렬되어 데이터가 삽입된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Sorted Table은 인덱스와 키로 둘 다 참조가 가능하다. 데이터가 내부적으로 정렬되기 때문에 이진 탐색이 가능하다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이진 탐색이란 쉽게 설명하자면 탐색 부분의 중간을 정하고 원하는 탐색 값이 중간보다 크거나 작은 지를 계산해 필요한 부분은 남기고 나머지 절반은 계속 버리면서 탐색하는 방법을 말한다. 절반은 계속 버려지기 때문에 $$(1/2)^n$$의 시간 복잡도. 즉 $$O(log&amp;nbsp; n)$$의 시간 복잡도를 가진다. Standard Table보다는 빠르지만 원하지 않아도 데이터가 정렬된다는 단점이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Hasehd Table&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;해시드 테이블이란 '해시'라는 고유의 주소값을 이용하는 테이블로, 테이블의 키 값을 '해싱 함수'라는 함수를 거쳐서 해시값으로 반환해주어 데이터를 참조하는 방식을 가진다. 키와 해시는 1:1로 매칭이 되어야 하기 때문에 해시드 테이블의 키는 꼭 'Unique' 해야 한다. (키와 해싱이 1:n으로 매칭이 되면 해시 충돌이 일어나게 된다.)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;테이블을 선언할 때 hashed 옵션 값을 주어 선언하며 with unique key가 꼭 명시되어야 한다.&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593483768626&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;TYPES: BEGIN OF TY_STUDENTS,
ID(8)          TYPE N,
NAME(30) TYPE C,
END OF TY_STUDENTS.
*Referring to local data type
DATA: LT_STUDENT_HSH TYPE HASHED TABLE OF TY_STUDENTS WITH UNIQUE KEY ID.&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;해시드 테이블은 키 값으로만 참조가 가능하다. 키와 해시는 1:1로 할당되므로 Hashed Table은 $$O(c)$$, 즉 상수의 시간 복잡도를 가져 가장 빠르다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&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/TK1dS/btqFeEcVce6/srDPMkfIfFguf4lSUd0tO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TK1dS/btqFeEcVce6/srDPMkfIfFguf4lSUd0tO1/img.png&quot; data-alt=&quot;다음과 같이 Standard, Sorted, Hashed 테이블이 만들어졌다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TK1dS/btqFeEcVce6/srDPMkfIfFguf4lSUd0tO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTK1dS%2FbtqFeEcVce6%2FsrDPMkfIfFguf4lSUd0tO1%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;figcaption&gt;다음과 같이 Standard, Sorted, Hashed 테이블이 만들어졌다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;어떤 테이블을 쓰는 지는 취향과 요구에 맞게 쓰면 된다. 필자의 과정에서는 Standard Table만 다뤄진다고 하니 앞으로의 포스팅도 Standard Table 위주로 다루려고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;테이블의 특징과 선언 방법을 알았으니 이제 데이터를 테이블에 불러오거나 테이블에 데이터를 담아주면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;헤더 라인이 있는 테이블과 없는 테이블&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;테이블의 구조적인 분류로 헤더 라인이 있는 테이블과 없는 테이블이 있다. 헤더 라인이 없는 테이블은 요즘 실무에서는 거의 사용하지 않는다고 한다&lt;s&gt;(라고 ABAP 강사님에게 들었다)&lt;/s&gt;. 때문에 이게 뭔지만 잠깐 알아보고 넘어가도록 하겠다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;헤더라인이 있는 테이블이란 테이블을 생성하면 헤더 라인이 자동적으로 생성되는 테이블을 말한다. 헤더 라인은 무엇인가? 위 '학생' 테이블에서 헤더 라인은 '이름', '나이', '학번' 등... 컬럼의 명세를 나타내는 것이다. 헤더 라인은 즉 컬럼의 정의를 Structure구조로 표현한 것이다.&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;헤더라인이 있는 테이블은 다음과 같이 WITH HEADER LINE 옵션을 주어 선언해 줄 수 있으며, 옵션을 주지 않은 기본값은 항상 헤더 라인이 없는 테이블이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593485053873&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;TYPES: BEGIN OF TY_STUDENTS,
ID(8)          TYPE N,
NAME(30) TYPE C,
END OF TY_STUDENTS.
*Referring to local data type
DATA LT_STUDENT_WITHHEADER TYPE TABLE OF TY_STUDENTS WITH HEADER LINE.&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: justify;&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;생성된 테이블을 디버그해보면 다음과 같이 Struture (헤더 라인)이 생성되어 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&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/cmes7K/btqFe2YG7I7/BvReLa7jSM0l7EMHRDdNPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cmes7K/btqFe2YG7I7/BvReLa7jSM0l7EMHRDdNPk/img.png&quot; data-alt=&quot;헤더라인(Structure)이 자동적으로 생성되었다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cmes7K/btqFe2YG7I7/BvReLa7jSM0l7EMHRDdNPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcmes7K%2FbtqFe2YG7I7%2FBvReLa7jSM0l7EMHRDdNPk%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;figcaption&gt;헤더라인(Structure)이 자동적으로 생성되었다.&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; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQA4np/btqFeCzpGBB/xc00fsHrXk4zfmIOfgB3Qk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQA4np/btqFeCzpGBB/xc00fsHrXk4zfmIOfgB3Qk/img.png&quot; data-alt=&quot;헤더라인의 내부&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQA4np/btqFeCzpGBB/xc00fsHrXk4zfmIOfgB3Qk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQA4np%2FbtqFeCzpGBB%2Fxc00fsHrXk4zfmIOfgB3Qk%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;figcaption&gt;헤더라인의 내부&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;' [ ] ' 가 붙은 Object 는 테이블 Body를 나타낸다. 헤더 라인이 있는 테이블은 데이터의 삽입과 추출을 생성된 헤더 라인을 이용해야 한다. 사용법이 다르지만 헤더 라인이 있는 테이블은 이제 잘 사용되지 않는다고 해서 더 이상 알아보지는 않겠다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;테이블에 데이터 삽입 및 조회&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;테이블은 Structure의 연속이다. 따라서 테이블에 데이터를 담아줄 때에는 담아주는 형식 역시 Structre와 동일한 형식을 가져야 한다. 즉, 테이블과 동일한 구조를 가진 Structure를 이용하여 테이블에 담아줘야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;데이타 타입과 그 타입을 참조하는 Structure, Standard Table을 선언하고 Structure에 값을 담아주겠다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1593486171136&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;TYPES: BEGIN OF TY_STUDENTS,
ID(8)          TYPE N,
NAME(30) TYPE C,
END OF TY_STUDENTS.

*Referring to local data type
DATA LS_STUDENT TYPE TY_STUDENTS.
DATA LT_STUDENT TYPE STANDARD TABLE OF TY_STUDENTS.

*Insert Values into Structure
LS_STUDENT-ID = 00000001.
LS_STUDENT-NAME = 'person_A'.
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;Structre LS_STUDENT에 위와 같이 값을 넣어준 후 Table LT_STUDENT에 데이터를 넣어주면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;데이터를 테이블에 삽입할 때에는 Insert 혹은 Append를 사용해 준다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Insert는 테이블의 특정 인덱스에 데이터를 넣을 경우 사용하고 Append는 항상 테이블의 마지막 로우에 데이터를 삽입해 준다. Insert에서 인덱스를 생략할 경우 마지막 줄에 삽입해준다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;다음과 같이 데이터를 넣어보자.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593486478151&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;*Insert Values into Structure
LS_STUDENT-ID = 00000001.
LS_STUDENT-NAME = 'person_A'.

*Insert Structure(row) Into Table
APPEND LS_STUDENT TO LT_STUDENT.
CLEAR LS_STUDENT.


LS_STUDENT-ID = 00000002.
LS_STUDENT-NAME = 'person_B'.

INSERT LS_STUDENT INTO TABLE LT_STUDENT.
CLEAR LS_STUDENT.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Insert에 인덱스를 주어 삽입도 해보자.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593486755632&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;LS_STUDENT-ID = 00000003.
LS_STUDENT-NAME = 'person_C'.

INSERT LS_STUDENT INTO LT_STUDENT INDEX 2.
CLEAR LS_STUDENT.&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이렇게 하면 테이블에 다음과 같은 데이터가 삽입되어있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&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/brAObs/btqFeO7vxOe/IU1M7Mi9H3b6wDbaKULml0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brAObs/btqFeO7vxOe/IU1M7Mi9H3b6wDbaKULml0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brAObs/btqFeO7vxOe/IU1M7Mi9H3b6wDbaKULml0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrAObs%2FbtqFeO7vxOe%2FIU1M7Mi9H3b6wDbaKULml0%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 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;앞서 설명한대로 Insert에 인덱스를 주었더니 가운데에 person_C가 삽입되었다. 위와 같이 빈 테이블에 데이터를 삽입해 줄 때에는 Insert보다는 Append를 써주는 게 낫다. Insert와 Append의 자세한 옵션까지 설명하자면 다음과 같다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;* 뒤에는 데이터오브젝트 혹은 필드 혹은 인덱스 값입니다.&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;i&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;˙APPEND LINES OF *table1 [FROM indexTO index] TO *table2&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;- 다수의 로우(레코드)를 추가할 때 사용한다. TABLE1의 index1 ~ index2 (생략 시 전체 범위)의 레코드를 TABLE2 맨 뒤에 확장한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;˙&lt;/span&gt;APPEND *structure TO *table SORTED BY *field&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;- 테이블에 데이터를 추가한 후 FIELD 기준으로 정렬한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; &lt;span style=&quot;color: #333333;&quot;&gt;˙INSERT LINES OF *table1[FROM index TO index] INTO *table2[INDEX index]&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;- Append와 비슷하지만 table2의 특정 인덱스에 데이터를 추가해 줄 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt; &lt;span style=&quot;color: #333333;&quot;&gt;˙INSERT LINES OF *table1 [FROM index TO index] INTO TABLE *table2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;- 위와 비슷하지만 테이블 형식에 제약이 없다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;위와 같이 Append와 Insert를 활용하여 Internal Table에 데이터를 넣어줄 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이번에는 Internal Table에 이미 기록된 데이터를 읽는 방법이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1593492446620&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;READ TABLE LT_STUDENT INDEX 1 INTO LS_STUDENT.
WRITE:/ LS_STUDENT-ID, LS_STUDENT-NAME.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Strutcture LS_STUDENT에 Table LT_STUDENT 첫 번째 인덱스가 삽입된다.&amp;nbsp;다음과 같이 LOOP문으로 테이블을 안의 값들을 순차적으로 읽어올 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593492555450&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;LOOP AT LT_STUDENT INTO LS_STUDENT.
  WRITE:/ LS_STUDENT-ID, LS_STUDENT-NAME.
  CLEAR LS_STUDENT.
ENDLOOP.

*or new ABAP expression
LOOP AT LT_STUDENT INTO DATA(IS_STUDENT).
  WRITE:/ IS_STUDENT-ID, IS_STUDENT-NAME.
  CLEAR IS_STUDENT.
ENDLOOP.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;i&gt;*참고) NEW ABAP은 버전 7.40 이후 새로 생긴 표현식이다&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #333333;&quot;&gt;테이블과 관련하여 시스템 변수 SY-TABIX가 매우 유용하게 쓰이니 이를 잘 활용하기 바란다. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #333333;&quot;&gt;그러나 TABIX가 중복돼서 사용될 경우 (LOOP 안에서 READ를 수행하는 경우가 그 예이다.) 의도하는 바와는 다른 결과가 초래될 수도 있다. READ를 할 경우 SY-TABIX가 READ문에 해당되는 테이블 INDEX로 갱신되기 때문에 원래의 TABLE INDEX를 나타내지 않기 때문이다. 이럴 경우 LOOP문 가장 처음 부분에서 TABIX를 변수 하나에 저장해두면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;데이터베이스에 있는 테이블(External Table)을 참조하여 Internal Table로 가져오는 방법도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;TCL (트랜잭션 제어어)라고 불리는 SQL이 그것인데, 이는 다음 SQL 포스팅에서 자세하게 다루도록 하겠다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>SAP/ABAP</category>
      <category>ABAP</category>
      <category>Internal Table</category>
      <author>cra4ckerjack</author>
      <guid isPermaLink="true">https://crackerjacks.tistory.com/15</guid>
      <comments>https://crackerjacks.tistory.com/15#entry15comment</comments>
      <pubDate>Tue, 30 Jun 2020 11:28:39 +0900</pubDate>
    </item>
    <item>
      <title>파이썬 (Python) - 깊은 복사 (Deep Copy)</title>
      <link>https://crackerjacks.tistory.com/14</link>
      <description>&lt;h2 style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;파이썬 (Python) - 깊은 복사 (Deep Copy)&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;알고리즘을 풀다 보면 원본배열의 보존을 위해 배열을 복사할 필요를 느낄때가 많다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;객체를 무작정 복사해서 사용하면 원본 객체가 핸들링되어 데이터가 변경되어서 큰 문제를 야기할 수 있기 때문에 객체를 복사할 때에는 주의해서 다뤄야 한다. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이번 포스팅에서는 객체를 복사하는 다양한 방법에 대해 알아보고자 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;객체를 복사하기 전에 먼저 객체의 특징 중 Mutable과 Immutable의 의미에 대해 알 필요가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;[Mutable, Immutable 객체]&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;파이썬에서 변수는 자신에게 대입된 객체를 가리키는 일종의 포인터 같은 존재이다. 때문에 파이썬에서 변수는 자체 저장공간을 할당받지 않으며 객체를 가리키는 개념이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;무슨 말인가?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;C언어에서 변수의 선언을 살펴보자.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593136453715&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int a = 1;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;위 Integer 자료형 변수 a는 1의 값을 가지며 변수 a와 1은 같은 존재라고 볼 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;파이썬에서 변수의 선언을 보면,&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593136499705&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a = 1&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;파이썬에서는 a와 1은 별개의 존재다. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;a라는 변수는 Integer 1이라는 객체를 가리키고 있을 뿐 a의 변수에 정수 1의 값이 할당 된 것이 아니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Mutable과 Immutable의 개념은 여기서 적용된다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Mutable과 Immutable은 글자 그대로, '변한다'와 '변하지 않는다' 라는 뜻을 가지고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;개념을 쉽게 이해하기 위해 다음과 같은 예시를 살펴보자.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593136754186&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a = 1
b = a
print(a, b) # 1 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;위 구문에서 a와 b는 동일하게 (정수 1) 이라는 객체를 가리키게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;여기서 b의 값을 2로 바꾸면 어떻게 될까?&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593137078024&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a = 1
b = a
print(a, b) # 1 1
b = 2
print(a, b) # 1 2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; font-size: 1.12em; letter-spacing: 0px;&quot;&gt;당현한 것처럼 위의 결과가 출력된다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이는 int의 자료형이 Immutable한 특징을 가졌기 때문에 그렇다. immutable한 객체는 생성이 된 후 값 수정이 불가능하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Mutable한 객체에는 대표적으로 list가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;파이썬에서 다음과 같이 배열을 선언해보고 출력해보자.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593137223306&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a = [1, 2, 3, 4]
b = a
print(a, b) # [1, 2, 3, 4] [1, 2, 3, 4]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;여기에, 위의 방식대로 b의 값을 바꾸면 어떨까?&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593137377056&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a = [1, 2, 3, 4]
b = a
print(a, b) # [1, 2, 3, 4] [1, 2, 3, 4]
b[1] = 0 # 배열 b의 두번째 값을 0으로 바꿔준다.
print(a, b) # [1, 0, 3, 4] [1, 0, 3, 4]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;위 결과와는 다르게 원본 배열 a의 두번째 값도 바뀌어 버렸다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이는 리스트가 Mutable한 특징을 가졌기에 값이 바뀔 수 있기 때문에 원본배열의 값이 바뀌어 버린 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;자세히 설명하자면, 위에서 a와 b는 같은 주소값을 참조한다. 그런데 list는 Mutable 하기 때문에 b의 값을 바뀌어 버리면 그 주소값에 있는 값을 바꾸어 버리기 때문에 같은 주소값을 참조하던 a도 값이 바뀌게 나오게 되는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1593148463033&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a = 1
b = a

print(id(a), id(b)) # id() 로 객체가 어떤 주소값(레퍼런스)를 확인하는지 알 수 있다.
print(a is b) # True.   is는 아이디 연산자로 객체가 같은 id값을 가지는지 T/F 를 반환한다.

c = [1, 2, 3, 4]
d = c

print(id(c), id(d)) 
print(c is d) # True&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;위 구문에서 a와 b, c와 d는 각각 동일한 레퍼런스(주소값)를 참조하고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;i&gt;*정수의 경우 -5 ~ 256 까지 기존 메모리에 생성되어있는 객체를 참조하기에 이 외의 값은 변수를 생성 할 때 다른 주소값을 참조하므로 정확한 말은 아니니 참고하세요&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;하지만 아까와 같은 방식으로 b와 d의 값을 바꿔보면..&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1593139001864&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;b = 0
d[1] = 0
print(id(a), id(b))
print(a is b) # False

print(id(c), id(d))
print(c is d) # True&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Integer형 변수는 Immutable 하므로 값이 바뀔 수 없어 다른 id값을 가지지만, &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;list형 변수는 Mutable하므로 값만 바뀌고 여전히 같은 주소값을 참조한다. 때문에 d의 값을 바꿔도 c의 값이 따라서 바뀌는 것이다.&lt;/span&gt;&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 style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;i&gt;참고) Mutable 자료형과 Immutable 자료형&lt;/i&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100.233%; height: 496px;&quot; border=&quot;1&quot; data-ke-style=&quot;style10&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;Class&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;구분&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;list&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: left;&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;순서가 있는 객체 집합&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;mutable&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;set&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: left;&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;순서가 없는 고유한 객체 집합&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;mutable&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;dict&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: left;&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;key와 value가 맵핑된 객체, 순서 없음&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;mutable&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;bool&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: left;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;True, False&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #333333; font-family: 'Nanum Gothic';&quot;&gt;immutable&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;int&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: left;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;정수&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #333333; font-family: 'Nanum Gothic';&quot;&gt;immutable&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;float&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: left;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;실수&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #333333; font-family: 'Nanum Gothic';&quot;&gt;immutable&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;tuple&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: left;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;순서가 있는 객체 집합&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #333333; font-family: 'Nanum Gothic';&quot;&gt;immutable&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;str&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: left;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;문자열&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #333333; font-family: 'Nanum Gothic';&quot;&gt;immutable&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;frozenset&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: left;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Immutable Set&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;immutable&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;i&gt;출처: &lt;a href=&quot;https://wikidocs.net/16038&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://wikidocs.net/16038&lt;/a&gt;&lt;/i&gt;&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;[얕은 복사(Shallow Copy) 와 깊은 복사(Deep Copy)]&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;위 개념이 이해가 되었으면 이제 어느정도 감이 잡혔을 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;얕은 복사는 객체를 새로운 객체로 복사하지만 원본 객체의 주소값을 복사하는 것이고, 깊은 복사는 전체 복사로 참조값의 복사가 아닌 참조된 객체 자체를 복사하는 것을 말한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;위 예제들에서 리스트들은 모두 얕은 복사를 통해 주소값만 복사되어서 복사된 객체에서 값을 바꾸었던 것이 Mutable한 list의 특성때문에 원본 객체의 값도 바뀐 것을 확인하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;코딩을 하다보면 원본 배열의 보존을 할 필요가 허다하기 때문에 이럴때는 배열을 '깊은 복사' 하여야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;단순함이 강점인 파이썬에서는 깊은 복사를 위한 여러가지 방법이 존재한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;- copy모듈의 deepcopy() 이용&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593140830862&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import copy

a = [1, 2, 3, 4]
b = copy.deepcopy(a)
b[1] = 0
print(a, b) # [1, 2, 3, 4] [1, 0, 3, 4]
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;가장 많이 쓰이는 방법으로 파이썬 내장 모듈 copy를 import 하여 deepcopy 메소드를 사용하는 방법이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;copy 모듈의 copy() 메소드와의 차이점은 copy() 는 배열의 내부 객체까지 깊은 복사를 해주지 않는 차이점이 있다. &lt;span style=&quot;color: #333333;&quot;&gt;(즉, 이중 이상의 배열은 완전한 깊은복사가 이루어지지 않음)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;- 클래스가 가지고있는 copy() 함수 이용&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593148517802&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a = [1, 2, 3, 4]
b = a.copy()
b[1] = 0
print(a,b) # [1, 2, 3, 4] [1, 0, 3, 4]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;파이썬의 기본적인 클래스들이 가지고있는 copy() 함수를 이용하는 것으로,&amp;nbsp; list 클래스 역시 copy() 함수를 가지고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;- list를 생성할 때 매개변수에 원본을 전달, 혹은 생성후 원본 리스트를 확장&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593141577052&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a = [1, 2, 3, 4]
b = list(a)
b[1] = 0
print(a,b) # [1, 2, 3, 4] [1, 0, 3, 4]&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1593141646572&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a = [1, 2, 3, 4]
b = []
b.extend(a)
b[1] = 0
print(a,b) # [1, 2, 3, 4] [1, 0, 3, 4]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;- 리스트 슬라이싱&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593141688652&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a = [1, 2, 3, 4]
b = a[:]
b[1] = 0
print(a,b) # [1, 2, 3, 4] [1, 0, 3, 4]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;- 배열 요소로의 접근을 통한 복사&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593145939678&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a = [1, 2, 3, 4]
b = [i for i in a]
b[1] = 0
print(a,b) # [1, 2, 3, 4] [1, 0, 3, 4]&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1593146113268&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a = [1, 2, 3, 4]
b = []
for i in range(len(a)):
    b.append(a[i])
b[1] = 0
print(a,b) # [1, 2, 3, 4] [1, 0, 3, 4]&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1593146163803&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a = [1, 2, 3, 4]
b = []
for item in a:
    b.append(item)
b[1] = 0
print(a,b) # [1, 2, 3, 4] [1, 0, 3, 4]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이렇게 다양한 방법을 통해 깊은 복사를 하면 값은 같더라도 기존에 있던 객체와는 완전히 다른 객체를 하나 만들어 낼 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;리스트 슬라이싱이나 제네릭 copy의 copy() 메소드는 리스트가 오브젝트를 포함할 경우 그 오브젝트들은 얕은복사되는 것만 주의해서 사용하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;어떤 방법을 쓰는게 좋을가? 취향에 따라 쓰면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;다만 각 방법 별로 처리속도가 다르니 이는 참고하는게 좋다. 처리속도는 리스트 슬라이싱이 가장 빠르고 copy 모듈의 deepcopy() 메소드가 가장 느리다고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;다음은 깊은복사 방법 별 처리속도를 정리한 것이니 참고 바라며 포스팅을 마친다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;lt;이하 &lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;출처:&lt;a style=&quot;color: #9d9d9d;&quot; href=&quot;https://stackoverflow.com/questions/2612802/how-to-clone-or-copy-a-list&quot;&gt;https://stackoverflow.com/questions/2612802/how-to-clone-or-copy-a-list&lt;/a&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;10.59 sec (105.9us/itn) -&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;http://docs.python.org/library/copy.html#copy.deepcopy&quot;&gt;copy.deepcopy(old_list)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;10.16 sec (101.6us/itn) - pure python&lt;span&gt;&amp;nbsp;&lt;/span&gt;Copy()&lt;span&gt;&amp;nbsp;&lt;/span&gt;method copying classes with deepcopy&lt;/li&gt;
&lt;li&gt;1.488 sec (14.88us/itn) - pure python&lt;span&gt;&amp;nbsp;&lt;/span&gt;Copy()&lt;span&gt;&amp;nbsp;&lt;/span&gt;method not copying classes (only dicts/lists/tuples)&lt;/li&gt;
&lt;li&gt;0.325 sec (3.25us/itn) -&lt;span&gt;&amp;nbsp;&lt;/span&gt;for item in old_list: new_list.append(item)&lt;/li&gt;
&lt;li&gt;0.217 sec (2.17us/itn) -&lt;span&gt;&amp;nbsp;&lt;/span&gt;[i for i in old_list]&lt;span&gt;&amp;nbsp;&lt;/span&gt;(a&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;http://docs.python.org/tutorial/datastructures.html#list-comprehensions&quot;&gt;list comprehension&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;0.186 sec (1.86us/itn) -&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;http://docs.python.org/library/copy.html#copy.copy&quot;&gt;copy.copy(old_list)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;0.075 sec (0.75us/itn) -&lt;span&gt;&amp;nbsp;&lt;/span&gt;list(old_list)&lt;/li&gt;
&lt;li&gt;0.053 sec (0.53us/itn) -&lt;span&gt;&amp;nbsp;&lt;/span&gt;new_list = []; new_list.extend(old_list)&lt;/li&gt;
&lt;li&gt;0.039 sec (0.39us/itn) -&lt;span&gt;&amp;nbsp;&lt;/span&gt;old_list[:]&lt;span&gt;&amp;nbsp;&lt;/span&gt;(&lt;a href=&quot;http://docs.python.org/tutorial/introduction.html#lists&quot;&gt;list slicing&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;코드로 직접 처리시간을 검증해 보려면 다음 코드를 실행해 보면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1593148589892&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from copy import deepcopy

class old_class:
    def __init__(self):
        self.blah = 'blah'

class new_class(object):
    def __init__(self):
        self.blah = 'blah'

dignore = {str: None, int: None, type(None): None}

def Copy(obj, use_deepcopy=True):
    t = type(obj)

    if t in (list, tuple):
        if t == tuple:
            # Convert to a list if a tuple to 
            # allow assigning to when copying
            is_tuple = True
            obj = list(obj)
        else: 
            # Otherwise just do a quick slice copy
            obj = obj[:]
            is_tuple = False

        # Copy each item recursively
        for x in range(len(obj)):
            if type(obj[x]) in dignore:
                continue
            obj[x] = Copy(obj[x], use_deepcopy)

        if is_tuple: 
            # Convert back into a tuple again
            obj = tuple(obj)

    elif t == dict: 
        # Use the fast shallow dict copy() method and copy any 
        # values which aren't immutable (like lists, dicts etc)
        obj = obj.copy()
        for k in obj:
            if type(obj[k]) in dignore:
                continue
            obj[k] = Copy(obj[k], use_deepcopy)

    elif t in dignore: 
        # Numeric or string/unicode? 
        # It's immutable, so ignore it!
        pass 

    elif use_deepcopy: 
        obj = deepcopy(obj)
    return obj

if __name__ == '__main__':
    import copy
    from time import time

    num_times = 100000
    L = [None, 'blah', 1, 543.4532, 
         ['foo'], ('bar',), {'blah': 'blah'},
         old_class(), new_class()]

    t = time()
    for i in range(num_times):
        Copy(L)
    print('Custom Copy:', time()-t)

    t = time()
    for i in range(num_times):
        Copy(L, use_deepcopy=False)
    print('Custom Copy Only Copying Lists/Tuples/Dicts (no classes):', time()-t)

    t = time()
    for i in range(num_times):
        copy.copy(L)
    print('copy.copy:', time()-t)

    t = time()
    for i in range(num_times):
        copy.deepcopy(L)
    print('copy.deepcopy:', time()-t)

    t = time()
    for i in range(num_times):
        L[:]
    print('list slicing [:]:', time()-t)

    t = time()
    for i in range(num_times):
        list(L)
    print('list(L):', time()-t)

    t = time()
    for i in range(num_times):
        [i for i in L]
    print('list expression(L):', time()-t)

    t = time()
    for i in range(num_times):
        a = []
        a.extend(L)
    print('list extend:', time()-t)

    t = time()
    for i in range(num_times):
        a = []
        for y in L:
            a.append(y)
    print('list append:', time()-t)

    t = time()
    for i in range(num_times):
        a = []
        a.extend(i for i in L)
    print('generator expression extend:', time()-t)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;참조 )&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a style=&quot;color: #9d9d9d;&quot; href=&quot;https://docs.python.org/ko/3/library/copy.html&quot;&gt;https://docs.python.org/ko/3/library/copy.html&lt;/a&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a style=&quot;color: #9d9d9d;&quot; href=&quot;https://wikidocs.net/20707&quot;&gt;https://wikidocs.net/20707&lt;/a&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a style=&quot;color: #9d9d9d;&quot; href=&quot;https://wikidocs.net/16038&quot;&gt;https://wikidocs.net/16038&lt;/a&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a style=&quot;color: #9d9d9d;&quot; href=&quot;https://webnautes.tistory.com/1181&quot;&gt;https://webnautes.tistory.com/1181&lt;/a&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a style=&quot;color: #9d9d9d;&quot; href=&quot;https://blueshw.github.io/2016/01/20/shallow-copy-deep-copy/&quot;&gt;https://blueshw.github.io/2016/01/20/shallow-copy-deep-copy&lt;/a&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a style=&quot;color: #9d9d9d;&quot; href=&quot;https://stackoverflow.com/questions/2612802/how-to-clone-or-copy-a-list&quot;&gt;https://stackoverflow.com/questions/2612802/how-to-clone-or-copy-a-list&lt;/a&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Python</category>
      <category>deep copy</category>
      <category>immutable</category>
      <category>mutable</category>
      <category>shallow copy</category>
      <category>깊은복사</category>
      <category>얕은복사</category>
      <category>파이썬</category>
      <author>cra4ckerjack</author>
      <guid isPermaLink="true">https://crackerjacks.tistory.com/14</guid>
      <comments>https://crackerjacks.tistory.com/14#entry14comment</comments>
      <pubDate>Fri, 26 Jun 2020 14:10:32 +0900</pubDate>
    </item>
    <item>
      <title>알고리즘 풀이 백준(BOI) 19235) 모노미노도미노 (Python)</title>
      <link>https://crackerjacks.tistory.com/11</link>
      <description>&lt;h2 style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;백준(BOI) 19235 - 모노미노도미노&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr style=&quot;border: none; font-size: 0px; line-height: 0; height: 20px; margin: 20px auto; background: url('https://t1.daumcdn.net/keditor/dist/0.4.0/image/divider-line.svg') 0px -160px / 200px 200px no-repeat #ffffff; cursor: pointer !important; width: 200px; color: #666666; font-family: 'Noto Sans', sans-serif; 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; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&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;figure id=&quot;og_1593065316496&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;19235번: 모노미노도미노&quot; data-og-description=&quot;모노미노도미노는 아래와 같이 생긴 보드에서 진행되는 게임이다. 보드는 빨간색 보드, 파란색 보드, 초록색 보드가 그림과 같이 붙어있는 형태이다.&amp;nbsp;게임에서 사용하는 좌표 (x, y)에서 x는 행, &quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/19235&quot; data-og-url=&quot;https://www.acmicpc.net/problem/19235&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/nG75B/hyGxa9diCz/bUO9m0ldvDSvhj5zb3h3KK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/dBp2ak/hyGx4sMMN6/N7i0yqgoiKOSOpjk3fJTVk/img.png?width=1246&amp;amp;height=1254&amp;amp;face=0_0_1246_1254,https://scrap.kakaocdn.net/dn/SGvRG/hyGx8WfIv5/K616ttGEDoZw0FjUUeE6J1/img.png?width=1228&amp;amp;height=1228&amp;amp;face=0_0_1228_1228&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/19235&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/19235&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/nG75B/hyGxa9diCz/bUO9m0ldvDSvhj5zb3h3KK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/dBp2ak/hyGx4sMMN6/N7i0yqgoiKOSOpjk3fJTVk/img.png?width=1246&amp;amp;height=1254&amp;amp;face=0_0_1246_1254,https://scrap.kakaocdn.net/dn/SGvRG/hyGx8WfIv5/K616ttGEDoZw0FjUUeE6J1/img.png?width=1228&amp;amp;height=1228&amp;amp;face=0_0_1228_1228');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;19235번: 모노미노도미노&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;모노미노도미노는 아래와 같이 생긴 보드에서 진행되는 게임이다. 보드는 빨간색 보드, 파란색 보드, 초록색 보드가 그림과 같이 붙어있는 형태이다.&amp;nbsp;게임에서 사용하는 좌표 (x, y)에서 x는 행,&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;[문제풀이]&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp; 도미노보다는 테트리스라고 생각하는게 더 편하다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;4 * 4 로 되어있는 빨간색 판에 블록을 놓으면 밑으로는 초록색 판(6*4)에 그대로 복사되고 오른쪽으로는 파란색 판(4*6)에 그대로 복사되어 각 각 벽쪽으로 테트리스처럼 내려가게 된다. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;왜 판을 두개 만들어 놓았을까? 빨간색 판에 놓인 블록을 파란색과 초록색 판이 서로 행과 열을 뒤집어 받게 되므로 같은 블록을 받아도 위치값이 다르게 되어 결과가 달라지기 때문이다. 때문에 초록색 판에서 테트리스가 아주 잘 되어 여러 줄이 지워져 블록이 거의 없지만 파란색 판에서는 반대로 엉망진창으로 블록이 쌓여있을 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이 문제는 위의 로직대로 테트리스(도미노)를&amp;nbsp; 여러번 수행하면서 점수를 계산하고 남아있는 블록을 출력해주는 문제이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;필자는 문제가 워낙 길고 조건이 복잡하여 문제를 이해하는데만 시간을 엄청 까먹었다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;게다가 우리가 아는 테트리스처럼 블록이 위까지 넘쳐버리면 끝나는게 아니라 초록색과 파란 판의 연한 부분 (초록판 윗부분 두 줄(row) , 파란판 왼쪽의 두 줄(col))에 블록이 존재하면 바닥의 줄을 지워버리므로 게임오버가 존재하지 않는다. (즉, 문제에서 주어지는&amp;nbsp; N만큼 무조건 돌아야 한다)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span&gt;근데 입력으로 주어지는 N의 범위가 10,000까지이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span&gt;삼성문제를 풀면서 처음으로 시간초과에 대한 걱정을 했고, &lt;span style=&quot;color: #ef6f53;&quot;&gt;역시나 시간초과를 3번이나 겪었다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;3번의 시간초과를 겪고 BOI 질문게시판에 게시글을 올리려고 코드를 정리하고 주석을 달던 중,&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;질문글을 올리기전에 마지막으로 제출을 해보고 올리려는 마음에 제출했는데 통과해버렸다. &lt;s&gt;&lt;i&gt;(이유가 뭐냐???)&lt;/i&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;질문게시판에 올리려고 이번 코드는 주석도 빵빵하다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;필자는 아직 코딩 초짜라 쌩구현만 할 줄 알지 (그것마저 미숙하다.) 다양한 알고리즘에 대한 기법은 알지 못한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span&gt;때문에 코드를 살펴보기 보기 보다는 로직의 이해에 도움이 되었으면 하는 바람에 이 글을 남긴다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;필자는 문제에서 주어진 로직을 다음과 같이 구현해서 풀었다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;코드에 주석이 있으니 메소드에 대한 해석은 코드를 참조 바란다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote style=&quot;text-align: justify;&quot; data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;#1. 입력(블록의 형태, 좌표)을 큐에 넣고 큐에 있는 블록들을 순서대로 빨간색 판에 놓는다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;#2. 빨간색 판에 있는 블록을 파란색 판과 초록색 판에 복사한다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;#3 - 1. 복사된 블록을 벽이나 다른 블록을 만나기 전까지 이동시킨다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;#3 - 2. 블록의 이동 후 한 줄이 모두 블록으로 채워져 있으면 해당 줄을 지우고 점수를 1점 올린다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;#3 - 3. 2에 해당되는 줄이 없으면 타일의 연한 부분에 블록이 있는지 확인하고 블록이 있다면 줄 개수 만큼 &lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;바닥 줄을 지운다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;#3 - 4. 이동을 반복한다. 위 2, 3에 해당되는 블록이 없을 때 종료된다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;#4. 블록을 모두 놓은 후 위 로직을 수행한 뒤 점수와 판에 남아있는 블록의 개수를 출력한다.&lt;/span&gt;&lt;/blockquote&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;style8&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;[전체 소스코드]&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1593067161733&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 초록판과 파란판의 연한 부분에 블록이 존재할 경우 존재하는 줄 수 만큼 바닥부분부터 줄을 지워주는 함수입니다.
def findDelete():
    global green, blue
    countGreen = 0; countBlue = 0;
    #초록판의 연한부분의 첫번째 줄 탐색
    for i in range(4):
        # 해당 줄에 블록이 하나라도 존재하면 나머지 부분은 탐색하지 않아도 됩니다.
        if green[0][i] &amp;gt; 0: countGreen += 1; break;
    #초록판의 연한부분의 두번째 줄 탐색    
    for i in range(4):
        if green[1][i] &amp;gt; 0: countGreen += 1; break;
        
    #파란판의 연한부분 탐색
    for i in range(4):
        if blue[i][0] &amp;gt; 0: countBlue += 1; break;
    for i in range(4):
        if blue[i][1] &amp;gt; 0: countBlue += 1; break;
    
    #연한부분에 있던 줄 수만큼 바닥의 줄을 지워줍니다.
    for i in range(countGreen):
        for j in range(4):
            green[5-i][j] = 0
    for i in range(4):
        for j in range(countBlue):
            blue[i][5-j] = 0
    
    #연한부분에 블록이 존재했는지 아닌지를 반환합니다.
    if countGreen == 0 and countBlue == 0 : return False
    else: return True
    
    
    
    
# moveBlock()에서 블록이 다중블록 (2*1, 1*2) 라면 그 인접 블록의 좌표도 찾아주는 함수입니다.
def findMultipleBlockState(i,j,value,isGreen):
    global green, blue
    result = []
    result.append([i,j])
    directions = (1, 0), (0, 1), (-1, 0), (0, -1)
    for dx, dy in directions:       
        if isGreen and 0 &amp;lt;= i + dx &amp;lt; 6 and 0 &amp;lt;= j + dy &amp;lt; 4 and green[i+dx][j+dy] == value: result.append([i+dx, j+dy]); break
        if not isGreen and 0 &amp;lt;= i + dx &amp;lt; 4 and 0 &amp;lt;= j + dy &amp;lt; 6 and blue[i+dx][j+dy] == value : result.append([i+dx, j+dy]); break
    return result

# 실질적으로 블록을 이동시켜주는 함수입니다. 1*1 뿐만 아니라 1*2, 2*1 블록도 같이 이동시켜주게 구현하였습니다.
def move(blockstate, value, isGreen):
    global green, blue
    nowx, nowy = blockstate[0]
    nearx, neary = (-1, -1)
    if len(blockstate) == 2 : nearx, neary = blockstate[1]
    if isGreen:
        while True:
            nextx = nowx + 1
            if nearx != -1: nextnearx = nearx + 1
            if nextx &amp;gt;= 6 or green[nextx][nowy] &amp;gt; 0 : break
            if nearx != -1 and green[nextnearx][neary] &amp;gt; 0 and green[nextnearx][neary] != value: break
            green[nextx][nowy] = value; green[nowx][nowy] = 0; nowx = nextx
            if nearx != -1: green[nextnearx][neary] = value; green[nearx][neary] = 0; nearx = nextnearx    
    else:
        while True:
            nexty = nowy + 1
            if neary != -1: nextneary = neary + 1
            if nexty &amp;gt;= 6 or blue[nowx][nexty] &amp;gt; 0 : break
            if neary != -1 and blue[nearx][nextneary] &amp;gt; 0 and blue[nearx][nextneary] != value: break
            blue[nowx][nexty] = value; blue[nowx][nowy] = 0; nowy = nexty
            if neary != -1: blue[nearx][nextneary] = value; blue[nearx][neary] = 0; neary = nextneary         


# 이동할 블럭을 탐색해주는 함수입니다. 
# go()상단에는 생성된 블록만 움직였지만 moveBlock()에서는 바닥부분을 제외한 모든 칸을 탐색합니다.(바닥부분은 이동이 불필요하므로)
def moveBlock():
    global green, blue
    for i in range(1,6):
        for j in range(4):
            # 초록부분 입니다.
            if green[5-i][j] &amp;gt; 0 : 
                #블록이 있는 경우 먼저 이 블록이 1*1 블록이 아닌지를 체크합니다.
                blockstate = findMultipleBlockState(5-i,j,green[5-i][j],True)
                #블록을 움직여주는 move()함수에 정보를 담아 보내줍니다.
                move(blockstate,green[5-i][j],True)         
            # 파랑부분 입니다.
            if blue[j][5-i] &amp;gt; 0 :
                blockstate = findMultipleBlockState(j,5-i,blue[j][5-i],False)
                move(blockstate,blue[j][5-i],False)    

            
# 블록의 이동 후 항상 확인해주는 메소드입니다. 한 row 혹은 col에 값이 모두 채워져 있을 경우 점수를 올리고 해당 줄을 지웁니다.                
def checkClear():
    global green, blue, answer
    resultg = []; resultb = []
    
    # 초록판 부분입니다.
    for i in range(4):
        count = 0
        for j in range(4):
            #칸이 0인경우 count변수에 -1을, 0아 아닌경우(블록이 있는경우) +1을 저장시킵니다.
            #종료조건을 주기 위해 블록의 가장 바닥부분부터 탐색합니다.
            if green[5-i][j] == 0 : count -= 1
            else : count += 1
        # 해당 줄이 모두 0인 경우 (즉, 비어있는 경우) 그 다음 줄은 당연히 블록이 없으므로 (중력에 의해) 반복문을 종료시켜줍니다.    
        if count == -4 : break
        # 해당 줄이 꽉 채워져있으면 해당 줄 index를 저장시킵니다.
        elif count == 4: resultg.append(5-i)
    
    # 파랑 판 부분입니다.
    for i in range(4):
        count = 0
        for j in range(4):
            if blue[j][5-i] == 0 : count -= 1
            else : count += 1
        if count == -4 : break
        elif count == 4 : resultb.append(5-i)    
        
        
    # 위에서 저장된 줄 index가 존재할 경우 해당 줄을 모두 0으로 바꿔주며 점수를 1점 올려줍니다. 
    if len(resultg) &amp;gt; 0 :
        for gx in resultg:
            answer += 1
            for j in range(4):
                green[gx][j] = 0
    if len(resultb) &amp;gt; 0:
        for by in resultb:
            answer += 1
            for i in range(4):
                blue[i][by] = 0    
                
    # 줄이 사라졌는지 안사라졌는지를 체크하기 위해 결과를 반환합니다.            
    if len(resultg)&amp;gt;0 or len(resultb)&amp;gt;0 : return True
    else: return False
   
 
 
 
   
# Main의 마지막 부분에서 그리드에 남은 블록 수를 출력하기 위해 이를 계산해주는 함수입니다.
def countBlock():
    global green, blue
    count = 0
    for i in range(6):
        for j in range(6):
            if i &amp;lt;= 3 and blue[i][j] &amp;gt; 0: count += 1
            if j &amp;lt;= 3 and green[i][j] &amp;gt; 0 : count += 1
    return count





# Main에서 호출하는 첫번째 함수입니다.
def go(param, index):
    global answer
    t, x, y = param
    # 먼저 받아낸 좌표값과 블록 모형을 Green, Blue에 각각 생성해줍니다.
    if t == 1: green[0][y] = index; blue[x][0] = index
    elif t == 2: green[0][y] = index; green[0][y+1] = index; blue[x][0] = index; blue[x][1] = index 
    else : green[0][y] = index; green[1][y] = index; blue[x][0] = index; blue[x+1][0] = index
    nowx = 0; nowy = 0
    
    # 위에서 생성된 블록을 벽이나 다른 블록에 부딛힐 때까지 움직입니다.
    # moveBlock() 함수를 호출해주는 것 보다 해당 로직을 다시한번 쓰는게 코드는 길어지더라도 
    # 시간은 짧아질 것 같아 굳이 한번 더 썼습니다. (탐색을 수행하지 않아도되므로)
    if t == 1:
        #move green
        while True:
            nextx = nowx + 1
            if nextx &amp;gt;= 6 or green[nextx][y] != 0: break
            green[nextx][y] = green[nowx][y]; green[nowx][y] = 0; nowx = nextx            
        #move blue
        while True:
            nexty = nowy + 1
            if nexty &amp;gt;= 6 or blue[x][nexty] != 0 : break
            blue[x][nexty] = blue[x][nowy]; blue[x][nowy] = 0; nowy = nexty
    elif t == 3:
        #move green
        nowx = 1
        while True:
            nextx = nowx + 1
            if nextx &amp;gt;= 6 or green[nextx][y] != 0: break
            green[nextx][y] = green[nowx][y]; green[nowx-1][y] = 0; nowx = nextx
        #move blue
        while True:
            nexty = nowy + 1
            if nexty &amp;gt;= 6 or blue[x][nexty] != 0 or blue[x+1][nexty] !=0 : break
            blue[x][nexty] = blue[x][nowy]; blue[x+1][nexty] = blue[x+1][nowy]; blue[x][nowy] = 0; blue[x+1][nowy] = 0; nowy = nexty
    else:
        #move green
        while True:
            nextx = nowx + 1
            if nextx &amp;gt;= 6 or green[nextx][y] != 0 or green[nextx][y+1] != 0 : break
            green[nextx][y] = green[nowx][y]; green[nextx][y+1] = green[nowx][y+1]; green[nowx][y] = 0 ; green[nowx][y+1] = 0; nowx = nextx
        nowy = 1
        #move blue
        while True:
            nexty = nowy + 1
            if nexty &amp;gt;= 6 or blue[x][nexty] != 0: break
            blue[x][nexty] = blue[x][nowy]; blue[x][nowy-1] = 0; nowy = nexty     
    
    
    # 이후 줄이 사라지거나 연한 그리드에 블록이 있을 경우 행을 삭제해주고 점수를 올려주는 방법을 반복합니다.
    # 점수계산과 줄의 삭제는 checkClear() 메소드에서, 연한부분의 탐색은 findDelete()에서 수행해줍니다.
    while True:
        # 만약 줄이 사라지지 않았고 연한 그리드에도 블록이 없으면 움직임을 종료합니다.  
        if checkClear() == False and findDelete() == False : break
        # 줄이 사라져 블록의 이동이 필요할 경우 moveBlock()이 이를 수행해줍니다.
        moveBlock()
        
# Main 입니다.
n = int(input())
# 입력값을 큐에 넣어 차례대로 돌립니다.
qu = []
for i in range(n):
    qu.append(list(map(int,input().split())))
green = [[0 for _ in range(4)] for _ in range(6)]
blue = [[0 for _ in range(6)] for _ in range(4)]
answer = 0; index = 1
while qu:
    go(qu.pop(0),index)
    index += 1
print(answer)  
print(countBlock())&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘</category>
      <category>19235</category>
      <category>Boi</category>
      <category>모노미노도미노</category>
      <category>백준</category>
      <category>삼성 SW 역량 테스트</category>
      <category>알고리즘</category>
      <category>파이썬</category>
      <author>cra4ckerjack</author>
      <guid isPermaLink="true">https://crackerjacks.tistory.com/11</guid>
      <comments>https://crackerjacks.tistory.com/11#entry11comment</comments>
      <pubDate>Thu, 25 Jun 2020 15:39:36 +0900</pubDate>
    </item>
    <item>
      <title>알고리즘 풀이 백준(BOI) 19238) 스타트 택시 (Python)</title>
      <link>https://crackerjacks.tistory.com/10</link>
      <description>&lt;h2 style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;백준(BOI) 19238 - 스타트 택시&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr style=&quot;border: none; font-size: 0px; line-height: 0; height: 20px; margin: 20px auto; background: url('https://t1.daumcdn.net/keditor/dist/0.4.0/image/divider-line.svg') 0px -160px / 200px 200px no-repeat #ffffff; cursor: pointer !important; width: 200px; color: #666666; font-family: 'Noto Sans', sans-serif; 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; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1592887149613&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;19238번: 스타트 택시&quot; data-og-description=&quot;첫 줄에 N,&amp;nbsp;M, 그리고 초기 연료의 양이 주어진다. (2&amp;nbsp;&amp;le; N&amp;nbsp;&amp;le; 20, 1&amp;nbsp;&amp;le; M&amp;nbsp;&amp;le; N2, 1&amp;nbsp;&amp;le; 초기 연료&amp;nbsp;&amp;le; 500,000) 연료는 무한히 많이 담을 수 있기 때문에, 초기 연료의 양을 넘어서 충전될 수도 있다. 다&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/19238&quot; data-og-url=&quot;https://www.acmicpc.net/problem/19238&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cBArBz/hyGxdbV6jR/KoyBG4qubFlbviXb6qGkAK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/6taeK/hyGvn1xSdb/HWxPmCgxpSpYNOEX3m6IKk/img.png?width=724&amp;amp;height=708&amp;amp;face=0_0_724_708,https://scrap.kakaocdn.net/dn/cFlrji/hyGvtgn9NS/gJBLva9pakXWSwwQlFsmSK/img.png?width=714&amp;amp;height=712&amp;amp;face=0_0_714_712&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/19238&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/19238&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cBArBz/hyGxdbV6jR/KoyBG4qubFlbviXb6qGkAK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/6taeK/hyGvn1xSdb/HWxPmCgxpSpYNOEX3m6IKk/img.png?width=724&amp;amp;height=708&amp;amp;face=0_0_724_708,https://scrap.kakaocdn.net/dn/cFlrji/hyGvtgn9NS/gJBLva9pakXWSwwQlFsmSK/img.png?width=714&amp;amp;height=712&amp;amp;face=0_0_714_712');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;19238번: 스타트 택시&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;첫 줄에 N,&amp;nbsp;M, 그리고 초기 연료의 양이 주어진다. (2&amp;nbsp;&amp;le; N&amp;nbsp;&amp;le; 20, 1&amp;nbsp;&amp;le; M&amp;nbsp;&amp;le; N2, 1&amp;nbsp;&amp;le; 초기 연료&amp;nbsp;&amp;le; 500,000) 연료는 무한히 많이 담을 수 있기 때문에, 초기 연료의 양을 넘어서 충전될 수도 있다. 다&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;[문제풀이]&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;택시가 승객들을 태우고 승객들의 목적지로 이동하는 문제이다. 승객들은 각각 고유한 자리에 존재하며 목적지 또한 고유하다. &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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 2배를 충전한다. 택시가 승객을 태우러 갈 수 없는 경우도 존재한다. 택시는 현재 택시의 위치에서 가장 가까운 승객을 다음 승객으로 &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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;선정한다. 이후 승객을 모두 태워서 목적지에 데려다주는 데 성공했으면 현재 남은 택시의 기름의 양을 출력하고 그렇지 않으면 -1을&amp;nbsp;&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&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;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;최단거리를 이용하는 문제이므로 승객을 선정할 때 BFS로 풀었다. 이 외에는 별 다른 특이한 점은 없었고 문제에서 주어지는 로직대로&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;시뮬레이션했다. 단, 주의할 점은 문제를 읽다 보면 승객을 태우러 갈 때 소비한 연료량과 태운 승객을 데리고 목적지로 갈 때 소비한&amp;nbsp;&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;또한 기름의 양이 초깃값은 최대 500,000 이고 이 후로 충전될 수 있는 양이 무한하므로 기름의 양으로 어떤 승객에게 도달할 수 있는&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&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;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;필자는 문제에서 주어진 로직을 다음과 같이 구현해서 풀었다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-size=&quot;size16&quot; data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;#1. 손님이 존재하는지 확인한다.&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&amp;nbsp;- isDone() 메소드 안에 구현하였다. 종료 조건이므로 While문 안에서 가장 먼저(혹은 마지막에) 체크해줘야 한다.&lt;br /&gt;&amp;nbsp;필자는 택시가 성공적으로 고객을 목적지까지 데려다 주면 해당 고객의 원래 위치를 그리드상에서 -1로 표시해줌으로써 구현하였다. -1의 개수가 M(손님의 수)와 맞다면 True를 리턴한다. isDone이 True를 리턴하면 프로세스는 종료된다.&lt;br /&gt;&lt;br /&gt;&lt;s&gt;제출하고 나니 막상 메소드를 따로 만들 필요도 없이 변수 하나를 만들어 count만 up 시켜줘도 되는 거였다...&lt;/s&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;#2. 존재하는 손님 중 가장 가까운 손님의 위치를 파악한다. 최단거리의 손님이 두 명 이상일 경우에는 행과 열의 값이 낮은 손님을 우선으로 한다.&lt;/b&gt;&lt;br /&gt;&amp;nbsp;- findNext(row, col) 메소드에 구현하였다. &lt;br /&gt;&amp;nbsp;먼저 현재 택시의 좌표를 큐에 넣어주고 택시의 좌표로부터 다른 모든 칸에 대한 거리 값을 계산한다(BFS). &lt;br /&gt;그리고 메소드의 아랫부분에서 최단거리인 손님과 손님들의 우선순위를 파악하고 해당 손님의 현재 좌표와 목적지의 좌표, 그리고 소모된 연료량을 리턴한다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;#3. 선정된 손님에게 이동하고 목적지로 이동한다.&lt;/b&gt;&lt;br /&gt;- move(now_row, now_col, destination_row, destination_col, fuel) 메소드에 구현하였다.&lt;br /&gt;&amp;nbsp;마찬가지로 최단거리로 이동하므로 BFS로 구현하였다. 목적지까지의 최단 거리를 리턴한다. 중간에 기름이 떨어졌으면 -1을 리턴한다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;#4. 위 (#3)에서 소비된 연료량의 두배를 충전한다.&lt;/b&gt;&lt;br /&gt;- 2에서 소비된 연료량은 충전 대상이 아니니 주의하자.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;#1~#4를 반복.&lt;br /&gt;&lt;/b&gt;루프 문 안에서 기름이 떨어지거나 손님이나 목적지에 도달할 수 없을 경우 -1을 리턴하는 종료 조건을 주었다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;다행히 시간 초과에 걸리지 않고 한 번의 시도만에 통과되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&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;style8&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;[전체 소스코드]&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1592889239118&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;
def isDone():
    global n, m, grid
    count = 0
    for i in range(n):
        for j in range(n):
            if grid[i][j] == -1: count += 1
    if count == m: return True
    else: return False
    
def move(x,y,destx,desty,f):
    global n, s, d, directions, grid
    count = [[-1 for _ in range(n)]for _ in range(n)]
    qu = []
    qu.append([x-1,y-1])
    count[x-1][y-1] = 0
    while qu:
        nowx, nowy = qu.pop(0)
        if nowx == destx -1 and nowy == desty -1 :
            if count[nowx][nowy] &amp;lt;= f : return count[nowx][nowy]
            else: return -1            
        for dx, dy in directions:
            nextx = nowx + dx
            nexty = nowy + dy
            if 0 &amp;lt;= nextx &amp;lt; n and 0 &amp;lt;= nexty &amp;lt; n and count[nextx][nexty] == -1 and grid[nextx][nexty] != 1:
                qu.append([nextx,nexty])
                count[nextx][nexty] = count[nowx][nowy] + 1
    return -1
    
def findNext(x,y):
    global n, s, d, directions, grid
    count = [[-1 for _ in range(n)]for _ in range(n)]
    qu = []
    qu.append([x-1,y-1])
    count[x-1][y-1] = 0
    while qu:
        nowx, nowy = qu.pop(0)
        for dx, dy in directions:
            nextx = nowx + dx
            nexty = nowy + dy
            if 0 &amp;lt;= nextx &amp;lt; n and 0 &amp;lt;= nexty &amp;lt; n and count[nextx][nexty] == -1 and grid[nextx][nexty] != 1:
                qu.append([nextx,nexty])
                count[nextx][nexty] = count[nowx][nowy] + 1   
    minNum = 987654321
    nextx, nexty, c = (22, 22, 0)
    destx, desty = (22, 22)
    for i in range(m):
        sx, sy = s[i]
        dx, dy = d[i]
        if count[sx-1][sy-1] != -1 and count[sx-1][sy-1]  &amp;lt;= minNum and grid[sx-1][sy-1] != -1:
            if count[sx-1][sy-1] == minNum:
                if sx &amp;lt; nextx : nextx, nexty, c = (sx, sy,count[sx-1][sy-1]); destx, desty = (dx, dy)
                elif sx == nextx and sy &amp;lt; nexty : nextx, nexty,c = (sx, sy,count[sx-1][sy-1]); destx, desty = (dx, dy)
            else: nextx, nexty, c = (sx, sy, count[sx-1][sy-1]); destx, desty = (dx, dy)
            minNum = count[sx-1][sy-1]
    return nextx, nexty, c, destx, desty

def go(nowx, nowy):
    global n, f, grid
    nowf = f
    while True:
        nextx, nexty, needf, destx, desty = findNext(nowx,nowy)
        if isDone() : break
        if nextx == 22 and nexty == 22 : return -1
        if nowf - needf &amp;lt; 0 : return -1
        nowf -= needf
        grid[nextx-1][nexty-1] = -1
        nowx, nowy = nextx, nexty
        needf = move(nowx,nowy,destx,desty,nowf)
        if needf == -1 : return -1
        else :
            nowf -= needf
            nowf += needf * 2
        nowx, nowy = destx,desty
    return nowf

n, m, f = map(int,input().split())
grid = [list(map(int,input().split())) for _ in range(n)]
tx, ty = map(int,input().split())
s = []; d = []
directions = (-1, 0), (0, -1), (1, 0), (0, 1) 
for i in range(m):
    temp = list(map(int, input().split()))
    s.append([temp[0],temp[1]])
    d.append([temp[2],temp[3]])
print(go(tx,ty))&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘</category>
      <category>19238</category>
      <category>Boi</category>
      <category>백준</category>
      <category>삼성 SW 역량 테스트</category>
      <category>스타트택시</category>
      <category>알고리즘</category>
      <category>파이썬</category>
      <author>cra4ckerjack</author>
      <guid isPermaLink="true">https://crackerjacks.tistory.com/10</guid>
      <comments>https://crackerjacks.tistory.com/10#entry10comment</comments>
      <pubDate>Tue, 23 Jun 2020 14:16:22 +0900</pubDate>
    </item>
    <item>
      <title>알고리즘 풀이 백준(BOI) 19237) 어른 상어(Python)</title>
      <link>https://crackerjacks.tistory.com/9</link>
      <description>&lt;h2 style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;백준(BOI) 19237 - 어른 상어&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr style=&quot;border: none; font-size: 0px; line-height: 0; height: 20px; margin: 20px auto; background: url('https://t1.daumcdn.net/keditor/dist/0.4.0/image/divider-line.svg') 0px -160px / 200px 200px no-repeat #ffffff; cursor: pointer !important; width: 200px; color: #666666; font-family: 'Noto Sans', sans-serif; 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; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&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;figure id=&quot;og_1592555813520&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;19237번: 어른 상어&quot; data-og-description=&quot;첫 줄에는 N, M, k가&amp;nbsp;주어진다. (2&amp;nbsp;&amp;le; N&amp;nbsp;&amp;le; 20, 2&amp;nbsp;&amp;le; M&amp;nbsp;&amp;le; N2, 1&amp;nbsp;&amp;le; k&amp;nbsp;&amp;le; 1,000) 그 다음 줄부터 N개의 줄에 걸쳐 격자의 모습이 주어진다. 0은 빈칸이고, 0이 아닌 수 x는 x번 상어가 들어있는 칸을 의미&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/19237&quot; data-og-url=&quot;https://www.acmicpc.net/problem/19237&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bif588/hyGsyPtHWs/qcDSlN46jOSAbC1ZjAbGnK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/ctUmLn/hyGtU4qjNR/xy6idg6OpWkNH9EvpU8TJ1/img.png?width=1802&amp;amp;height=716&amp;amp;face=0_0_1802_716,https://scrap.kakaocdn.net/dn/zJ6ul/hyGstm6gXZ/MjXiQqPvmR46EiUIl0TSsK/img.png?width=1804&amp;amp;height=714&amp;amp;face=0_0_1804_714&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/19237&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/19237&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bif588/hyGsyPtHWs/qcDSlN46jOSAbC1ZjAbGnK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/ctUmLn/hyGtU4qjNR/xy6idg6OpWkNH9EvpU8TJ1/img.png?width=1802&amp;amp;height=716&amp;amp;face=0_0_1802_716,https://scrap.kakaocdn.net/dn/zJ6ul/hyGstm6gXZ/MjXiQqPvmR46EiUIl0TSsK/img.png?width=1804&amp;amp;height=714&amp;amp;face=0_0_1804_714');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;19237번: 어른 상어&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;첫 줄에는 N, M, k가&amp;nbsp;주어진다. (2&amp;nbsp;&amp;le; N&amp;nbsp;&amp;le; 20, 2&amp;nbsp;&amp;le; M&amp;nbsp;&amp;le; N2, 1&amp;nbsp;&amp;le; k&amp;nbsp;&amp;le; 1,000) 그 다음 줄부터 N개의 줄에 걸쳐 격자의 모습이 주어진다. 0은 빈칸이고, 0이 아닌 수 x는 x번 상어가 들어있는 칸을 의미&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;[문제풀이]&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;상어의 움직임을 시뮬레이션하면서 어른상어(1번 상어)만 남을 때의 카운팅을 출력하는 문제이다. 상어의 움직임 조건이 상당히 복잡&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;별한 점은 없었다.&amp;nbsp;&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;주의할 점은 상어의 방향을 정해줄 때 &lt;u&gt;냄새가 없는 공간을 먼저 탐색하고&lt;/u&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&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;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;문제에서 주어진 로직은 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-size=&quot;size16&quot; data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;1. 상어가 자신이 있는 자리에 냄새를 남긴다. (냄새는 상어의 번호를 가지며 일정한 시간 뒤 사라진다.)&lt;br /&gt;2. 모든상어가 동시에 이동한다. 상어는 이동 할 때 다음 기준을 따른다. 한 번의 이동은 1초이다.&lt;br /&gt;&amp;nbsp; &amp;nbsp;2-1. 상어가 바라보는 방향에 대한 우선순위를 참조하여 다음 방향을 결정한다. 다음 방향이 다른 상어의 냄새가 없는 빈 칸이라면 방향 결정.&lt;br /&gt;&amp;nbsp; &amp;nbsp;2-2. 위 2-1)만족되는 방향이 없으면 (즉, 빈 칸이 없으면) 왔던 방향으로 (자신의 냄새가 있는 칸으로) 돌아간다.&lt;br /&gt;3. 한 칸에 상어가 두 마리 이상 있으면 가장 낮은 번호의 상어를 제외하고는 소멸한다.&lt;br /&gt;4. 위 로직을 계속 반복하면서 1번 상어만 남게 될 때 몇초인지 출력한다. 1000초가 지나면 -1을 출력한다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;상어가 &quot;동시에&quot; 이동하며 한 칸에 여러마리의 상어가 들어갈 때 가장 낮은 상어만 남는 것을 구현하기 위해 그리드를 2&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&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;s&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;여담이지만 삼성 문제는 시간과 메모리에서 항상 여유가 있는 것 같다.&lt;/span&gt;&lt;/s&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&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;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;[전체 소스코드]&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1592558355032&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;
def makeStateGrid():
    global grid, n
    statearr = [(-1,-1) for _ in range(m)]
    for i in range(n):
        for j in range(n):
            if grid[i][j] &amp;gt; 0:
                statearr[grid[i][j]-1] = (i,j)
    return statearr

def copy(grid2):
    global n, grid
    arr = list()
    for i in range(n):
        for j in range(n):
            if len(grid2[i][j]) &amp;gt;= 1:                
                for num in grid2[i][j]:
                    arr.append(num)
                arr.sort()
                grid[i][j] = arr.pop(0)
                arr.clear()

def move():
    global grid, smellgrid, dirstatarr, dirgrid, n, m
    grid2 = [[[] for _ in range(n)] for _ in range(n)]
    statearr = makeStateGrid()
    for i in range(m):
        nowx, nowy = statearr[i]
        if nowx == -1 or nowy == -1 : continue
        nowdir = dirstatarr[i] - 1
        oper = True
        for j in range(4):
            nextdir = dirgrid[i][nowdir][j] - 1
            dx, dy = directions[nextdir]
            nextx = nowx + dx
            nexty = nowy + dy
            if 0 &amp;lt;= nextx &amp;lt; n and 0 &amp;lt;= nexty &amp;lt; n and len(smellgrid[nextx][nexty])==0:
                grid2[nextx][nexty].append(i+1)
                grid[nowx][nowy] = 0
                dirstatarr[i] = nextdir + 1
                oper = False
                break
        if oper:
            for j in range(4):
                nextdir = dirgrid[i][nowdir][j] - 1
                dx, dy = directions[nextdir]
                nextx = nowx + dx
                nexty = nowy + dy
                if 0 &amp;lt;= nextx &amp;lt; n and 0 &amp;lt;= nexty &amp;lt; n and len(smellgrid[nextx][nexty])&amp;gt;0 and smellgrid[nextx][nexty][0] == i+1:
                    grid2[nextx][nexty].append(i+1)
                    grid[nowx][nowy] = 0
                    dirstatarr[i] = nextdir + 1
                    oper = False
                    break                
                
            
    copy(grid2)

def spread():
    global grid, smellgrid, n, k
    for i in range(n):
        for j in range(n):
            if len(smellgrid[i][j]) &amp;gt; 0 :
                smellgrid[i][j][1] -= 1
            if len(smellgrid[i][j]) &amp;gt; 0 and smellgrid[i][j][1] == 0: smellgrid[i][j].clear()
    for i in range(n):
        for j in range(n):
            if grid[i][j] &amp;gt; 0 :
                smellgrid[i][j] = [grid[i][j], k]

def check():
    global grid, n
    for i in range(n):
        for j in range(n):
            if grid[i][j] &amp;gt; 1: return False    
    return True



n, m, k = map(int,input().split())
grid = [list(map(int,input().split())) for _ in range(n)]
smellgrid = [[[] for _ in range(n)] for _ in range(n)]
dirstatarr = list(map(int, input().split()))
dirgrid = [[]for _ in range(m)]
answer = 0
directions = (-1, 0), (1, 0), (0, -1), (0, 1)
for i in range(m):
    for t in range(4):
        temp = list(map(int,input().split()))
        dirgrid[i].append(temp)
                    
while True:
    if answer &amp;gt;= 1000 : answer = -1; break;
    answer += 1
    spread()
    move()
    if check() : break
    
print(answer)&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>알고리즘</category>
      <category>19237</category>
      <category>Boi</category>
      <category>백준</category>
      <category>삼성 SW 역량 테스트</category>
      <category>알고리즘</category>
      <category>어른 상어</category>
      <category>파이썬</category>
      <author>cra4ckerjack</author>
      <guid isPermaLink="true">https://crackerjacks.tistory.com/9</guid>
      <comments>https://crackerjacks.tistory.com/9#entry9comment</comments>
      <pubDate>Fri, 19 Jun 2020 18:19:51 +0900</pubDate>
    </item>
    <item>
      <title>알고리즘 풀이 백준(BOI) 17779) 게리맨더링 2 (Python)</title>
      <link>https://crackerjacks.tistory.com/8</link>
      <description>&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;백준(BOI) 17779 - 게리맨더링 2&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr style=&quot;border: none; font-size: 0px; line-height: 0; height: 20px; margin: 20px auto; background: url('https://t1.daumcdn.net/keditor/dist/0.4.0/image/divider-line.svg') 0px -160px / 200px 200px no-repeat #ffffff; cursor: pointer !important; width: 200px; color: #666666; font-family: 'Noto Sans', sans-serif; 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; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1592535691184&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;17779번: 게리맨더링 2&quot; data-og-description=&quot;재현시의 시장 구재현은 지난 몇 년간 게리맨더링을 통해서 자신의 당에게 유리하게 선거구를 획정했다. 견제할 권력이 없어진 구재현은&amp;nbsp;권력을 매우 부당하게 행사했고, 심지어는 시의 이름��&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/17779&quot; data-og-url=&quot;https://www.acmicpc.net/problem/17779&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cTkIrb/hyGsuF38HJ/uBP77quS6DH7SqmkFuPUk1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/0UVpL/hyGtQnc9cL/MXWMfSKCzqTAZuOp5BIG41/img.png?width=1014&amp;amp;height=1022&amp;amp;face=0_0_1014_1022,https://scrap.kakaocdn.net/dn/ct35IF/hyGsIqNHVF/eBui5ItBBqNZTBHisQgMEk/img.png?width=902&amp;amp;height=910&amp;amp;face=0_0_902_910&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/17779&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/17779&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cTkIrb/hyGsuF38HJ/uBP77quS6DH7SqmkFuPUk1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/0UVpL/hyGtQnc9cL/MXWMfSKCzqTAZuOp5BIG41/img.png?width=1014&amp;amp;height=1022&amp;amp;face=0_0_1014_1022,https://scrap.kakaocdn.net/dn/ct35IF/hyGsIqNHVF/eBui5ItBBqNZTBHisQgMEk/img.png?width=902&amp;amp;height=910&amp;amp;face=0_0_902_910');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;17779번: 게리맨더링 2&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;재현시의 시장 구재현은 지난 몇 년간 게리맨더링을 통해서 자신의 당에게 유리하게 선거구를 획정했다. 견제할 권력이 없어진 구재현은&amp;nbsp;권력을 매우 부당하게 행사했고, 심지어는 시의 이름��&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;[문제풀이]&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;선거구를 5개로 분할하여&amp;nbsp; 각 선거구에 있는 사람들을 합하였을 때 가장 많은 사람이 있는 선거구와 가장 적은 사람이 있는 선거구의&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;최소값을 구하는 문제이다. 선거구는 문제에 주어져 있는 공식대로 분할되며 시작점을 어디로 하는 지에 따라 여러가지 경우의 수가&amp;nbsp;&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;나올 수 있다. 필자는 브루트포스로 모든 경우의 수를 계산하여 각 경우의 수 마다 최소값을 갱신하는 방식으로 풀었다.&amp;nbsp;&amp;nbsp;&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;선거구의 경계를 나누는 방식에서 1 ~ 4 번 선거구 먼저 할당해주고 5번 선거구의 경계선을 그려주고 경계선 안의 구역을 5번으로&amp;nbsp;&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;채우는 방식으로 풀었다. 문제를 풀다가 5번 선거구 경계선 안쪽을 5번 선거구로 채우는 과정에서 실수를 한 번 했었는데,&amp;nbsp;&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;다음과 같은 경우는 탐색을 이용해서 5번 선거구를 채울 수 없으므로 반복문 조건을 잘 짜주어서 채우는 방식으로 해결하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-size=&quot;size16&quot; data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp;0&amp;nbsp; 5&amp;nbsp; 0&amp;nbsp; 0&lt;br /&gt;&amp;nbsp;5&amp;nbsp; &amp;nbsp; &amp;nbsp; 5&amp;nbsp; 0&lt;br /&gt;&amp;nbsp;0&amp;nbsp; 5&amp;nbsp; &amp;nbsp; &amp;nbsp; 5&lt;br /&gt;&amp;nbsp;0&amp;nbsp; 0&amp;nbsp; 5&amp;nbsp; 0&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;위와 같은 경우에서는 탐색을 이용하여 경계선 안쪽을 매꿀 수가 없었다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #9d9d9d;&quot;&gt;&lt;i&gt;&amp;nbsp;(빈 칸을 0으로 그려놨지만 알고리즘에서 1 ~ 4번 선거구 먼저 채워주었으므로 더욱 그렇다)&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;i&gt;&amp;nbsp;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;문제에서 주어진 로직은 다음과 같다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span&gt;&amp;nbsp;1. 기준점 (row, col)과 경계선의 길이(d1, d2)를 정한다.&lt;br /&gt;&amp;nbsp;2. 주어진 공식대로 경계선을 그린다.&lt;br /&gt;&amp;nbsp;3. 경계선과 경계선 안의 구역을 5번 선거구로 채운다.&lt;br /&gt;&amp;nbsp;4. 경계선 밖의 구역은 주어진 공식대로 1, 2, 3, 4번 선거구로 채운다.&lt;br /&gt;&amp;nbsp;5. 인구가 가장 많은 선거구와 가장 적은 선거구의 인구 차이의 &lt;b&gt;&lt;u&gt;최솟값&lt;/u&gt;&lt;/b&gt;을 구한다.&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;주어진 로직대로라면 5번 선거구 먼저 채우고 1~4번 선거구를 확정지어야 하지만 필자는 1~4번 선거구 먼저 채웠다.&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;문제의 공식은 row, col 값이 0이 아닌 1부터 시작하므로 이것만 주의해서 공식을 작성하면 쉽게 통과 될 수 있을 것이다.&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;브루트포스로 풀은데다가 별다른 종료조건을 주지 않아 메모리와 시간초과가 걱정되었지만 무난히 통과하였다&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;[전체 소스코드]&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1592536674859&quot; class=&quot;python&quot; style=&quot;display: block; overflow: auto; padding: 15px; color: #383a42; background: #f6f7f8; font-size: 14px; border-radius: 3px; font-family: Menlo, Consolas, Monaco, monospace; border: 1px solid #dddddd; 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-style: initial; text-decoration-color: initial;&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;
def calc(sepgrid):
    global n, objgrid,minresult
    maxnum = -987654321
    minnum = 987654321
    result = [0 for _ in range(5)]
    for i in range(n):
        for j in range(n):
            if sepgrid[i][j] == 1 : result[0] += objgrid[i][j]
            elif sepgrid[i][j] == 2 : result[1] += objgrid[i][j]
            elif sepgrid[i][j] == 3 : result[2] += objgrid[i][j]
            elif sepgrid[i][j] == 4 : result[3] += objgrid[i][j]
            elif sepgrid[i][j] == 5 : result[4] += objgrid[i][j]
    for num in result:
        maxnum = max(num,maxnum)
        minnum = min(num,minnum)
    minresult = min(maxnum-minnum, minresult)
    
    
def separate(row,col,d1,d2):
    global n
    sepgrid = [[0 for _ in range(n)] for _ in range(n)]
    
  
    #sep1
    for i in range(row+d1):
        for j in range(col+1):
            sepgrid[i][j] = 1
    #sep2 
    for i in range(row+d2+1):
        for j in range(col+1,n):
            sepgrid[i][j] = 2
    
    #sep3 
    for i in range(row+d1, n):
        for j in range(col-d1+d2):
            sepgrid[i][j] = 3
    
    #sep4
    for i in range(row+d2+1,n):
        for j in range(col-d1+d2,n):
            sepgrid[i][j] = 4

    #sep5
    temp = col
    for i in range(row, row+d1+1):
        sepgrid[i][temp] = 5
        temp -= 1
    temp = col
    for i in range(row, row+d2+1):
        sepgrid[i][temp] = 5
        temp += 1
    temp = col-d1
    for i in range(row+d1, row+d1+d2+1):
        sepgrid[i][temp] = 5
        temp += 1
    temp = col+d2
    for i in range(row+d2, row+d2+d1+1):
        sepgrid[i][temp] = 5
        temp -= 1
    for i in range(row+1,row+d1+d2):
        oper = False
        for j in range(0, n):
            if sepgrid[i][j] == 5 and not oper : 
                oper = True 
                continue
            if oper and sepgrid[i][j] == 5 : oper = False
            if oper : sepgrid[i][j] = 5

    calc(sepgrid)

def go(row, col):
    global n
    for d1 in range(1,n-1):
        for d2 in range(1,n-1):
            if 1 &amp;lt;= (row+1) &amp;lt; (row+1)+d1+d2 &amp;lt;= n and 1 &amp;lt;= (col+1)-d1 &amp;lt; (col+1) &amp;lt; (col+1) + d2 &amp;lt;= n:
                separate(row,col,d1,d2) 

n = int(input())
objgrid = [list(map(int,input().split())) for _ in range(n)]
minresult = 987654321
for i in range(n-2):
    for j in range(1,n-1):
        go(i,j)

print(minresult)
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘</category>
      <category>17779</category>
      <category>Boi</category>
      <category>게리맨더링 2</category>
      <category>백준</category>
      <category>삼성 SW 역량 테스트</category>
      <category>알고리즘</category>
      <category>파이썬</category>
      <author>cra4ckerjack</author>
      <guid isPermaLink="true">https://crackerjacks.tistory.com/8</guid>
      <comments>https://crackerjacks.tistory.com/8#entry8comment</comments>
      <pubDate>Fri, 19 Jun 2020 12:19:04 +0900</pubDate>
    </item>
  </channel>
</rss>