[BOJ] #17140 이차원 배열과 연산 Python

현지·2021년 10월 11일
0

BOJ

목록 보기
39/44

문제

https://www.acmicpc.net/problem/17140

크기가 3×3인 배열 A가 있다. 배열의 인덱스는 1부터 시작한다. 1초가 지날때마다 배열에 연산이 적용된다.

  • R 연산: 배열 A의 모든 행에 대해서 정렬을 수행한다. 행의 개수 ≥ 열의 개수인 경우에 적용된다.
  • C 연산: 배열 A의 모든 열에 대해서 정렬을 수행한다. 행의 개수 < 열의 개수인 경우에 적용된다.

한 행 또는 열에 있는 수를 정렬하려면, 각각의 수가 몇 번 나왔는지 알아야 한다. 그 다음, 수의 등장 횟수가 커지는 순으로, 그러한 것이 여러가지면 수가 커지는 순으로 정렬한다. 그 다음에는 배열 A에 정렬된 결과를 다시 넣어야 한다. 정렬된 결과를 배열에 넣을 때는, 수와 등장 횟수를 모두 넣으며, 순서는 수가 먼저이다.

예를 들어, [3, 1, 1]에는 3이 1번, 1가 2번 등장한다. 따라서, 정렬된 결과는 [3, 1, 1, 2]가 된다. 다시 이 배열에는 3이 1번, 1이 2번, 2가 1번 등장한다. 다시 정렬하면 [2, 1, 3, 1, 1, 2]가 된다.

정렬된 결과를 배열에 다시 넣으면 행 또는 열의 크기가 달라질 수 있다. R 연산이 적용된 경우에는 가장 큰 행을 기준으로 모든 행의 크기가 변하고, C 연산이 적용된 경우에는 가장 큰 열을 기준으로 모든 열의 크기가 변한다. 행 또는 열의 크기가 커진 곳에는 0이 채워진다. 수를 정렬할 때 0은 무시해야 한다. 예를 들어, [3, 2, 0, 0]을 정렬한 결과는 [3, 2]를 정렬한 결과와 같다.

행 또는 열의 크기가 100을 넘어가는 경우에는 처음 100개를 제외한 나머지는 버린다.

배열 A에 들어있는 수와 r, c, k가 주어졌을 때, A[r][c]에 들어있는 값이 k가 되기 위한 최소 시간을 구해보자.

입력

첫째 줄에 r, c, k가 주어진다. (1 ≤ r, c, k ≤ 100)

둘째 줄부터 3개의 줄에 배열 A에 들어있는 수가 주어진다. 배열 A에 들어있는 수는 100보다 작거나 같은 자연수이다.

출력

A[r][c]에 들어있는 값이 k가 되기 위한 연산의 최소 시간을 출력한다. 100초가 지나도 A[r][c] = k가 되지 않으면 -1을 출력한다.

아이디어

✅ 조건에 맞을 때까지 반복을 한다.

  • Counter을 이용해서 각 숫자가 몇 개씩 존재하는지 확인했다.
  • 열 정렬을 할 때, 미리 만들어둔 행 정렬 함수를 사용하기 위해 행과 열을 zip을 이용해서 바꾸고, 다시 행과 열을 바꾼다.

✔️ 코드 설명
1. 인덱스가 넘어가지 않는 범위 내에서 k와 같은지 확인한다.
2. 같지 않다면 시간을 하나 증가시킨다. 만약 시간이 100초를 넘어가면 중단한다.
3. 행의 길이가 열보다 크거나 같으면 행 정렬을 한다.
4. 아니면 행, 열을 바꿔서 정렬을 한 후 다시 행, 열을 바꾼다.

👍 sort1() 함수

1. 행의 수만큼 반복을 한다.
2. Counter을 이용하여 각 숫자의 개수를 세서 key와 value를 따로 저장한다.
3. 0은 정렬할 때 사용하지 않으므로 0이 아닌 경우만 tmp에 저장하고 정렬한다.
4. 가장 긴 길이를 저장하기 위해 s에 가장 긴 행의 길이를 저장한다.
5. 길이가 맞지 않으면 가장 긴 길이에 맞춰 0을 채운다.
6. 길이가 100을 넘어가면 잘라준다.

내 코드_python

from collections import Counter

r, c, k = map(int, input().split())
arr = [list(map(int, input().split())) for x in range(3)]

#인덱스 하나씩 줄이기
r -= 1
c -= 1
time = 0

#조건에 맞게 정렬 시키는 함수
def sort():
    s = 0
    for i in range(len(arr)):
        key = list(Counter(arr[i]).keys())
        value = list(Counter(arr[i]).values())
        tmp = []
        for j in range(len(key)):
            if key[j] != 0: #0인 경우는 정렬하지 않음
                tmp.append([key[j], value[j]])
        tmp.sort(key=lambda x: (x[1], x[0]))
        arr[i] = sum(tmp, [])
        s = max(len(arr[i]), s)

    #가장 긴 길이에 맞춰서 0 채우기
    for i in range(len(arr)):
        if len(arr[i]) != s:
            n = s - len(arr[i])
            arr[i] += [0] * n
            arr[i] = arr[i][:100]


while 1:
    #조건 맞으면 중단, 범위 맞지 않을 수 있음 indexError 조심하기
    if len(arr) > r and len(arr[0]) > c:
        if arr[r][c] == k:
            break
    time += 1
    if time > 100:  #100초가 지나면 안됨
        time = -1
        break
    #행 정렬
    if len(arr) >= len(arr[0]):
        sort()
    #열 정렬
    else:
        arr = list(map(list, zip(*arr)))
        sort()
        arr = list(map(list, zip(*arr)))

print(time)

0개의 댓글