본문 바로가기

백준 파이썬 코딩

백준 17140 이차원 배열과 연산 파이썬 *추가*

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

 

17140번: 이차원 배열과 연산

첫째 줄에 r, c, k가 주어진다. (1 ≤ r, c, k ≤ 100) 둘째 줄부터 3개의 줄에 배열 A에 들어있는 수가 주어진다. 배열 A에 들어있는 수는 100보다 작거나 같은 자연수이다.

www.acmicpc.net

전 포스팅에서 R연산하고 C연산을 둘다 구현했는데 인터넷 서칭을 해보니 굳이 그럴 필요없이 zip(*s)를 통해 행과 열을 바꿀 수 있다는 것을 알았다...

이 방법을 사용하니 시간도 줄어들고 코드가 매우 간단해졌다. 오늘도 배워간다..(나중에 써먹어야겠다.)

def R(s): #R연산을 해주는 함수
    maxs=-1#행의 길이의 최댓값
    for i in range(len(s)):
        s2=[]#정렬된 리스트가 담길 리스트
        c=0#행의 길이
        for k in set(s[i]):#시간 복잡도를 줄이기 위해 set을 사용
            if k!=0:
                s2.append([s[i].count(k),k])#s[i]배열에 있는 k의 개수를 k와 함께 저장. 
        s2.sort()#정렬된 상태로 집어 넣으니 정렬해줌
        s[i]=[]#인덱스 하나하나 바꿔주는 방법도 있으나 시간 복잡도상으로 append를 써도 돼 빈리스트로 만든 뒤 추가해줌
        for o in s2:#s2에는 [[k개수,k],...,[k개수,k]]상태로 저장돼있음
            s[i].append(o[1])#정렬은 [k,k개수]이런 형식으로 정렬되니 저런 작업을 해줌
            s[i].append(o[0])
            c+=2#행의 길이가 2만큼 늘어나니 +2
        maxs = max(maxs,c)#최댓값 갱신
    for i in range(len(s)):
        s[i]+=[0]*(maxs-len(s[i]))#최댓값에 비해 부족한 길이를 더해줌
    

  
r,c,k=map(int,input().split())

s = [list(map(int,input().split())) for _ in range(3)]
t=0

try:#처음부터 정답인 경우는 바로 출력 r,c가 리스트 범위를 벗어날 수 있으니 예외처리 
    if s[r-1][c-1]==k:
        print(t)
        t=102
except:
        pass

    
while t<=100:#최대 100번이니 t가 100보다 크거나 같을때까지만 
    t+=1
    rl,cl = len(s),len(s[0])#R연산인지 C연산인지 확인해주기 위한것
    
    if rl>=cl:
        R(s)
    else:
        s=list(zip(*s))#행열 바꿔줌
        R(s)
        s=list(zip(*s))#행열 다시 바꿔줌
   
    try:연산후 정답인 경우는 바로 출력 r,c가 리스트 범위를 벗어날 수 있으니 예외처리
        if s[r-1][c-1]==k:
            print(t)
            break
    except:
        pass
    
if t==101:#100번 연산했는데 답이 안 나왔음으로 -1 출력
    print(-1)