반응형
Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
05-19 00:03
관리 메뉴

ImJay

[파이썬/Python] 백준 2816번 디지털 티비 본문

백준 - 문제집/대학생 기본반

[파이썬/Python] 백준 2816번 디지털 티비

ImJay 2023. 1. 16. 13:49
반응형

[파이썬/Python] 백준 2816번 디지털 티비

 

2816번: 디지털 티비

2012년 12월 31일 새벽 4시부터 지상파 아날로그 TV방송이 종료되었다. TV를 자주보는 할머니를 위해서, 상근이네 집도 디지털 수신기를 구입했다. 원래 상근이네 집에는 KBS1과 KBS2만 나왔다. 할머니

www.acmicpc.net


문제

2012년 12월 31일 새벽 4시부터 지상파 아날로그 TV방송이 종료되었다. TV를 자주보는 할머니를 위해서, 상근이네 집도 디지털 수신기를 구입했다.

원래 상근이네 집에는 KBS1과 KBS2만 나왔다. 할머니는 두 방송만 시청한다. 이제 디지털 수신기와 함께 엄청난 양의 채널을 볼 수 있게 되었다.  하지만, 할머니는 오직 KBS1과 KBS2만 보려고 한다. 따라서, 상근이는 채널 리스트를 조절해 KBS1을 첫 번째로, KBS2를 두 번째로 만들려고 한다.

티비를 켜면 디지털 수신기는 시청 가능한 채널 리스트를 보여준다. 모든 채널의 이름은 서로 다르고, 항상 KBS1과 KBS2를 포함하고 있다. 상근이는 이 리모콘을 이용해서 리스트의 순서를 바꾸는 법을 알아냈다. 리스트의 왼편에는 작은 화살표가 있고, 이 화살표는 현재 선택한 채널을 나타낸다. 가장 처음에 화살표는 제일 첫 번째 채널을 가리키고 있다.

다음과 같은 네 가지 버튼을 이용해서 리스트의 순서를 바꿀 수 있다. 각각은 1번부터 4번까지 번호가 적혀져있는 버튼이다.

  1. 화살표를 한 칸 아래로 내린다. (채널 i에서 i+1로)
  2. 화살표를 위로 한 칸 올린다. (채널 i에서 i-1로)
  3. 현재 선택한 채널을 한 칸 아래로 내린다. (채널 i와 i+1의 위치를 바꾼다. 화살표는 i+1을 가리키고 있는다)
  4. 현재 선택한 채널을 위로 한 칸 올린다. (채널 i와 i-1의 위치를 바꾼다. 화살표는 i-1을 가리키고 있다)

화살표가 채널 리스트의 범위를 넘어간다면, 그 명령은 무시한다.

현재 채널 리스트의 순서가 주어졌을 때, KBS1를 첫 번째로, KBS2를 두 번째로 순서를 바꾸는 방법을 구하는 프로그램을 작성하시오. 방법의 길이는 500보다 작아야 한다. 두 채널을 제외한 나머지 채널의 순서는 상관없다.

 

해설

1. 시작점에서 화살표는 0이고, 'KBS1'을 찾을 때 까지 1번 버튼을 사용해야 한다.

2. 'KBS1'을 찾았다면, 4번 버튼을 통해 'KBS1'을 시작점까지 위로 계속 옮긴다.

3. 'KBS2' 도 동일하게 찾는다.

 

위 1,2,3 과정을 수행한다면 버튼1과 버튼4 기능만 구현하면 된다.

문제의 조건 중 채널의 수는 100개 이하이고, 방법의 길이는 500 미만이다.

버튼 1과 버튼 4만 사용하면서 'KBS1', ;KBS2'가 각각 99, 100번에 위치 하더라도,

100 * 4 = 400 이므로 방법의 길이가 500을 넘지 않는다.

코드

def cursorDown(cursor):
    cursor += 1
    print(1, end='')
    return cursor  

def channelUp(cursor):
    if cursor > 0:
        cList[cursor], cList[cursor-1] = cList[cursor-1], cList[cursor]
        cursor -= 1
        print(4, end='')
    return cursor

cList = []

for _ in range(int(input())):
    cList.append(input()) 
    
cursor = 0
while True:
    if cList[cursor] != 'KBS1':
        cursor = cursorDown(cursor)
    else:
        cursor = channelUp(cursor)
    if cList[0] == 'KBS1':
        break

while True:
    if cList[cursor] != 'KBS2':
        cursor = cursorDown(cursor)
    else:
        cursor = channelUp(cursor)
    if cList[1] == 'KBS2':
        break

 

풀이

def cursorDown(cursor):
    cursor += 1
    print(1, end='')
    return cursor

1. 버튼1을 구현한 cursorDown 함수이다.

커서를 1 증가시키고, '1'을 출력한다. 그리고 증가된 커서를 반환한다.

 

def channelUp(cursor):
    if cursor > 0:
        cList[cursor], cList[cursor-1] = cList[cursor-1], cList[cursor]
        cursor -= 1
        print(4, end='')
    return cursor

2. 버튼4를 구현한 channelUp 함수이다.

커서가 0보다 크다는 조건이 필요하다.(0일 경우 인덱스가 -1로 이동하기 때문)

채널 i와 i-1의 위치를 바꾸고, 화살표는 i-1을 가리키도록 한다.

'4'를 출력하고, 커서를 반환한다.

 

cList = []

for _ in range(int(input())):
    cList.append(input())

3. 메인 메서드 부분이다.

비어있는 채널리스트를 선언하고, 입력된 채널 수만큼 채널을 입력 받아 채널리스트에 할당한다.

 

cursor = 0
while True:
    if cList[cursor] != 'KBS1':
        cursor = cursorDown(cursor)
    else:
        cursor = channelUp(cursor)
    if cList[0] == 'KBS1':
        break

4. 커서를 0으로 초기화하고,

채널리스트에서 'KBS1'을 순차적으로 찾아준다.'KBS1'이 아닐 경우 커서를 내리고, 'KBS1'이라면 채널을 위로 올린다.'KBS1'이 1번채널(인덱스 0)까지 옮겨졌다면, 루프를 탈출한다.

 

while True:
    if cList[cursor] != 'KBS2':
        cursor = cursorDown(cursor)
    else:
        cursor = channelUp(cursor)
    if cList[1] == 'KBS2':
        break

5. 'KBS2'도 해당 과정을 똑같이 반복한다.

다른 점은, 'KBS2'가 2번채널(인덱스 1)까지 옮겨졌다면, 루프를 탈출하도록 한다.

코드 중복이 불편하다면 따로 메소드로 만들어주고, 문자열을 파라미터로 받는 방식으로 구현해도 될 것 같다!

 

피드백

'KBS1', 'KBS2'에 해당하는 인덱스를 직접 찾아서 그 수 만큼 1과 4를 출력하는 방법이 아마 실행시간에 있어서 조금 더 빠르지 않을까 싶다.

문제에 접근하는 방법에 대해 조금 더 생각을 해볼 필요가 있는 것 같다.

물론 아직 문제를 많이 풀지 않았기 때문에, 이런 고민이 섣부를 수도 있다.

빨리 많은 문제를 접해보는게 더 시급하다!

 

 

반응형
Comments