[Algorithm] 역수열 (그리디)

myeonji·2022년 2월 1일
0

Algorithm

목록 보기
24/89

1부터 n까지의 수를 한 번씩만 사용하여 이루어진 수열이 있을 때, 1부터 n까지 각각의 수 앞에 놓여 있는 자신보다 큰 수들의 개수를 수열로 표현한 것을 역수열이라 한다. 예를 들어 다음과 같은 수열의 경우 4 8 6 2 5 1 3 7
1앞에 놓인 1보다 큰 수는 4, 8, 6, 2, 5. 이렇게 5개이고,
2앞에 놓인 2보다 큰 수는 4, 8, 6. 이렇게 3개,
3앞에 놓인 3보다 큰 수는 4, 8, 6, 5 이렇게 4개......
따라서 4 8 6 2 5 1 3 7의 역수열은 5 3 4 0 2 1 1 0 이 된다. n과 1부터 n까지의 수를 사용하여 이루어진 수열의 역수열이 주어졌을 때, 원래의 수열을 출력하는 프로그램을 작성하세요.

<내 답안>

n = int(input())
li = list(map(int, input().split()))

a = [x for x in range(1, n+1)]
tmp = [0 for _ in range(n)]

for i in range(n):
    cnt = 0
    for j in range(n):
        if cnt == li[i]:
            break
        if tmp[j] == 0:
            cnt += 1
    if tmp[j] != 0:
        j+=1
    tmp[j] = i+1
    print(tmp)

[0, 0, 0, 0, 0, 1, 0, 0][0, 0, 0, 2, 0, 1, 0, 0]
[0, 0, 0, 2, 0, 1, 3, 0][4, 0, 0, 2, 0, 1, 3, 0]
[4, 0, 0, 2, 5, 1, 3, 0][4, 0, 6, 2, 5, 1, 3, 0]
[4, 0, 6, 7, 5, 1, 3, 0][4, 8, 6, 7, 5, 1, 3, 0]
출력이 이렇게 되는데 이유를 모르겠어서 한참을 고민했다. 6번째 출력에서 7번째 출력으로 넘어갈 때 7이 왜 2자리에 오게 되는지.. j를 출력해보니 j는 7이 되어야 하는데 3이 출력된다. 분명 맞게 한 거 같은데..
오랜 고민 끝에 문제를 알아냈다. if tmp[j] != 0 이 아니라 while 문을 써야했다. 나는 무의식적으로 if문을 계속 while문으로 엄두해두고 코드를 검사하고 있었다.. 머리는 while문을 생각하는데 손은 if문을 쓰다니..

어쨌든.. 저거 바꾸니까 다 해결됐다 ㅠㅠ!!

n = int(input())
li = list(map(int, input().split()))

tmp = [0 for _ in range(n)]

for i in range(n):
    cnt = 0
    for j in range(n):
        if cnt == li[i]:
            break
        if tmp[j] == 0:
            cnt += 1
    while tmp[j] != 0:
        j+=1
    tmp[j] = i+1

for x in tmp:
    print(x, end=' ')

<모범답안>

n = int(input())
a = list(map(int, input().split()))
seq = [0]*n

for i in range(n):
    for j in range(n):
        if a[i] == 0 and seq[j] == 0:
            seq[j] = i+1
            break
        elif seq[j] == 0:
            a[i] -= 1
for x in seq:
    print(x, end=' ')

오늘도 나를 괴롭게 하는 모범답안ㅎ 이거.. 이렇게 간단한거니..?
if문에 a[i]의 갯수를 줄여나가면 되는구나..

seq[j]가 0일 때마다 a[i]를 줄여서 a[i]개 만큼의 빈 공간을 만든다. 그리고 a[i] == 0임과 동시에(앞에 빈공간이 a[i]개인 동시에) seqj가 0이 되면 그 자리에 i+1이 들어가면 된다.
즉, 앞에 빈공간이 a[i]개만큼 있으면서 현재 자리가 비어있으면 그 자리에 들어가면 된다.

0개의 댓글