Jindory
Jindory의 기록 라이프
Jindory
전체 방문자
오늘
어제
06-18 15:38
  • 분류 전체보기
    • 개발
      • AI
      • Java
      • Javascript
      • JPA
      • Python
      • Spring
      • Web
    • 데이터베이스
      • Database
      • Oracle
      • MySQL
    • 코딩테스트
      • 구름IDE
      • 백준
      • 코딩테스트 준비
      • 프로그래머스
    • 분석 및 설계
      • Design Pattern
      • UML
    • 트러블슈팅
      • Java
      • JPA
      • Spring
    • 개발 커리어
      • 면접
      • 멘토링
      • 포트폴리오
      • 프로젝트

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

최근 댓글

최근 글

티스토리

250x250
hELLO · Designed By 정상우.
Jindory

Jindory의 기록 라이프

[백준] 17140번 : 이차원 배열과 연산(Python)
코딩테스트/백준

[백준] 17140번 : 이차원 배열과 연산(Python)

2022. 3. 22. 00:12
반응형

문제

크기가 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을 출력한다.

전체코드(Pythono)

from collections import Counter
def operation(m,dir):
    # 가로 연산인 경우 배열을 그대로 저장하지만
    if dir=='R':
        box = m
    # 세로 연산인 경우 행과 열을 전환한다.
    else:
        box = list(zip(*m))
    # 어차피 배열의 개수만큼 가로가 나올것이므로 result는 box의 길이만큼 []를 만든다.
    result = [[] for _ in range(len(box))]
    large = 0
    for loop in range(len(box)):
        temp = []
        # 0의 개수는 세면 안 되므로, 배열에서 0보다 큰 수들만 뺀다.
        box[loop] = list(filter(lambda x:x>0,box[loop]))
        # 행에 있는 숫자들의 개수를 센다
        count = Counter(box[loop])
        # 행에 있는 숫자들(중복없는)을 num에 저장한다.
        num = list(set(box[loop]))
        # temp에 숫자와 숫자의 개수를 임시로 저장한다.
        for i in range(len(num)):
            temp.append([num[i],count[num[i]]])
        
        # 숫자의 개수대로 오름차순 정렬하고 숫자의 개수가 동일하다면 숫자의 오름차순으로 정렬한다.
        temp = sorted(temp,key=lambda x:(x[1],x[0]))
        # 나중에 가장 긴 배열의 크기만큼 0을 채워야 하므로 larage에 가장 긴 배열의 크기를 저장한다.
        large = len(temp)*2 if large < len(temp)*2 else large
        # 정렬한 숫자들을 숫자,숫자개수 순서로 result에 추가한다.
        for i in range(len(temp)):
            result[loop].append(temp[i][0])
            result[loop].append(temp[i][1])
    # 다 정리된 숫자들을 전체 길이에 맞게 추가한다. 짧은 배열은 0으로 채운다.
    for i in range(len(result)):
        for loop in range(large-len(result[i])):
            result[i].append(0)
        # 행 또는 열의 크기가 100을 넘어가는 경우에는 처음 100개를 제외한 나머지는 버린다.
        result[i] = result[i][:100]
    # 세로 연산인 경우 다시 세로로 만들어 준다.
    if dir=='C':
        result = list(zip(*result))
    return result

# r과 c와 k를 입력 받는다.
r,c,k = map(int,input().split())
# 처음에는 3x3 배열이므로 3x3 배열을 만든다.
m = [ [0]*3 for _ in range(3)]

# 3x3 반복문을 돌며 matrix에 값을 입력받는다.
for y in range(3):
    temp = list(map(int,input().split()))
    for x in range(3):
        m[y][x] = temp[x]
# 연산을 한 시간
loop = 0

flag = True
# matrix의 r-1, c-2 이 k거나 시간이 100을 넘어가면 반복문을 탈출한다.
while flag: 
    # 만일 변형한 matrix가 r보다 가로가 짧거나 c보다 세로가 짧을 경우가 있으므로 이 경우에는 matrix r-1,c-1을 구하지 않고 연산만 한다.
    if len(m)>=r and len(m[0])>=c:
        if m[r-1][c-1]!=k and loop<100:
            loop+=1
            # 행 개수가 열보다 크거나 같으면 가로 연산을 한다.
            if len(m) >= len(m[0]):
                m = operation(m,'R')
            else:        
                m = operation(m,'C')
        else:
            flag = False
    else:
        if loop <100:
            loop+=1
            # 행 개수가 열보다 크거나 같으면 가로 연산을 한다.
            if len(m) >= len(m[0]):
                m = operation(m,'R')
            else:        
                m = operation(m,'C')
        else:
            flag = False

# 탈출 했을때 구하고자 하는 배열의 크기와 안 맞으면 정답을 못 찾은것이므로 -1
if len(m)>=r and len(m[0])>=c:
    # 정답을 찾은 시점이 100초 이하라면 구한 시간을 출력(100을 포함)
    if loop <= 100 and m[r-1][c-1]==k:
        print(loop)
    else:
        print(-1)
else:
    print(-1)

알아야할 함수들

  • map(int,input().split())
    • map(자료형,변형할 대상) :  변형할 대상을 자료형으로 변형한다.
    • input() : 외부로부터 입력값을 받는다.
    • split() : 괄호안에 값을 기준으로 문자열을 분할한다(아무것도 없을시 띄어쓰기로 분할)
  • list(zip(*m))
    • zip(*iterable) : zip은 동일한 개수로 이루어진 자료형을 묶어 주는 역할을 하는 함수이다. 위 문제에서 행과 열을 바꿔주는데 사용했다.
      list(zip([1,2,3],[4,5,6])     -> [(1,4),(2,5),(3,6)]
  • list(filter(lambda x:x>0,box[loop]))
    • filter(function,iterable) : 함수에 맞는 조건으로 반복 가능한 자료형을 필터링하여 반환하는 함수이다.
      [ list로 감싸지 않을경우 iterator형으로 나오므로 list로 변환을 해 주자 ]
  • Counter(box[loop)
    • Counter : collections에 있는 하나의 메서드로 순환 가능한 자료형에서 아이템들의 개수를 세서 반환한다.
      • 예시 : ex_list = ['kim','kim','park','choi','kim','kim','kim','choi','park','choi']
        print(collections.Counter(ex_lixt))      # Counter({'kim':5,'choi':3,'park':2})
      • 각 아이템의 개수를 개수만큼 만드는것도 가능하다.
        ex) ex_counter = collections.Counter(kim=3,park=2,choi=3)
             print(sorted(ex_counter.elements()))      # ['choi','choi','choi','kim','kim','kim','park','park']
  • list(set(box[loop]))
    • set : 중복없이 순환가능한 자료형의 아이템들을 집합으로 만든다.
      list로 감싸면 list형으로 형변환이 된다.
  • sorted(temp,key=lambda x:(x[1],x[0])
    • sorted : 원래 순환가능한 자료형의 원본을 변형시키지 않고 정렬하는 방법이며, 안에 사용자 정의 함수를 통해 정렬방식을 정할 수 있다.( 안에 선언된 사용자 정의 함수는 temp 배열의 각 아이템들의 2번째 요소로 오름차순 2번째 요소가 같을경우 1번째 요소로 오름차순한다는 의미이다) [ 역순정렬을 하고 싶다면 앞에 -를 붙히면 된다.)
  • result[i][:100]
    • result[i]의 배열을 100개까지만 저장하하겠다는 의미이다.

 

혹시라도 정정할 내용이나 추가적으로 필요하신 정보가 있다면 댓글 남겨주시면 감사하겠습니다.

오늘도 Jindory 블로그에 방문해주셔서 감사합니다.

 

[ 참조 ]

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

반응형
저작자표시 비영리 (새창열림)

'코딩테스트 > 백준' 카테고리의 다른 글

[백준] 2864번 : 5와 6의 차이(Python)  (0) 2022.03.18
[백준] 2217번 : 로프(Python)  (0) 2022.03.18
[백준] 1748번 : 수 이어 쓰기1  (0) 2022.03.18
[백준] 11725번 : 트리의 부모 찾기(Python)  (0) 2022.03.17
[백준] 10026번 : 적록색약(Python)  (0) 2022.03.17
    '코딩테스트/백준' 카테고리의 다른 글
    • [백준] 2864번 : 5와 6의 차이(Python)
    • [백준] 2217번 : 로프(Python)
    • [백준] 1748번 : 수 이어 쓰기1
    • [백준] 11725번 : 트리의 부모 찾기(Python)
    Jindory
    Jindory

    티스토리툴바