백준 2738번 행렬 덧셈 pyton

kimminjunnn·2024년 12월 23일

알고리즘

목록 보기
5/311
post-thumbnail

2738번: 행렬 덧셈

N*M 크기의 행렬 두개를 더하는 문제.

우선 행렬을 어떻게 받을까?

#첫 번째 행렬 A 입력 받기
A = []
for _ in range(N):
       row = list(map(int, input().split()))
       A.append(row)

#두 번째 행렬 A 입력 받기
B = []
for _ in range(N):
       row = list(map(int, input().split()))
       B.append(row)

배열을 선언하고 배열안에 배열을 넣는 방식으로 입력 받았다.

그러면 두개를 어떻게 더하지?
이중 반복문을 이용하면 돼.

#결과 행렬 result 초기화
result = []

for i in range(N):
       row = []
       for j in range(M):
              row.append(A[i][j] + B[i][j])
       result.append(row)

빈 배열 row 를 선언하고 거기다가 A행렬의 NM 요소 + B행렬의 NM 요소 더하고 그것을 result 배열에 넣는것을 반복하면 돼.

그러면 출력은 어떻게 하지?
배열을 다 풀어서 출력할때는 print(*result) 를 활용하면 되잖아?

현재 result 배열은 이중배열로 되어있으니 배열 하나씩 꺼내서 출력하려면 for 반복문을 써야해

for row in result:
	print(*row)

를 하면 한 줄씩 꺼내져서 나오게 됨.

기본적인 이중배열 문제 인 것 같아 잘 숙지해둬야 나중에 고생안하겠다.
머릿속에 넣어두자

전체 코드

N, M = map(int,input().split())

#첫 번째 행렬 A 입력 받기
A = []
for _ in range(N):
       row = list(map(int, input().split()))
       A.append(row)

#두 번째 행렬 A 입력 받기
B = []
for _ in range(N):
       row = list(map(int, input().split()))
       B.append(row)
       
#결과 행렬 result 초기화
result = []

for i in range(N):
       row = []
       for j in range(M):
              row.append(A[i][j] + B[i][j])
       result.append(row)

for row in result:
       print(*row)

2566번: 최댓값

9x9 행렬을 받고, 최댓값을 출력하고, 최대값의 행,열 번호를 출력하는 문제.

행렬을 받아보자.

matrix = []

for i in range (9):
       row = list(map(int,input().split()))
       matrix.append(row)

  1. 빈 배열을 선언한다.
  2. for문 몇줄의 row를 받을지 range에 넣고 돌린다.
    2-1. row라는 배열을 list(map(int,input().split())) 콤보를 이용해서 만들고 matrix 배열에 넣는다. range 수 만큼 반복한다.

이제 행렬을 순회하면서 최댓값을 구해야겠지?
이중 배열이니까 이중 반복문을 이용하여 순회해야할거야.

biggest_num 라는 변수를 선언하고, if 조건문으로, 매트릭스를 순회하면서 biggest_num보다 큰 숫자를 발견하면 그 숫자를 biggest_num에 넣는 방식으로 짜볼게.

biggest_num = matrix[0][0]
row_num = 1
col_num = 1

#biggest_num ,row_num, col_num 변수 선언하기.

#행렬 순회하면서 최댓값 찾기
for i in range(len(matrix)): #행 번호
       for j in range(len(matrix[i])): #열 번호
              if matrix[i][j] > biggest_num:
                     biggest_num = matrix[i][j]
                     row_num = i+1
                     col_num = j+1
print(biggest_num)
print(row_num,col_num) 

순회는 또 아까위에 더하기랑 다른 로직이더라구

len 을 이용하는데
결국에 뭘하고싶은거냐면 우리는 matrix[i][j] 를 가져오는걸 원하는 거잖아?
그러니까 행과 열의 개수인 m,n 을 구해야하는데 그것이 바로
len(matrix) = m 와 len(matrix[i]) = n 이야.

row_num,col_num 은 0부터 시작하니까 +1 처리 해준 것

핵심을 정리하자면
이중 반복문:
for i in range(len(matrix)): 행렬의 행을 순회.
for j in range(len(matrix[i])): 각 행의 열을 순회.

최댓값 비교:
if matrix[i][j] > biggest_num: 현재 값이 저장된 biggest_num보다 크면 갱신.
biggest_num을 업데이트하고, 해당 값의 위치(행과 열 번호)를 row_num과 col_num에 저장


10798번: 세로읽기

문자열을 다섯번 입력 받고,
해당 문자열을 세로로 읽는 문제. (공백이라면 다음 문자를 읽음)

어떻게 풀까.
우선 배열로 문자열을 다섯번 받아야겠다
크기가 15인. 공백으로 가득 찬 배열 5개.

arrays = []

for i in range(5):
       string = input()
       array = list(string) + [""] * (15 - len(string)) 
       arrays.append(array)

array1,array2,array3,array4,array5 = arrays

15개의 칸 중 string의 길이만큼 빼준 칸을 공백으로 채움.

이제는 각 array의 0번째 index부터 result 배열에 추가하여 담으면 된다. 공백을 포함하여 다 담고 마지막에 공백제거하여 읽으면 되겠다.

result = []

for i in range(15):
    result.append(array1[i])
    result.append(array2[i])
    result.append(array3[i])
    result.append(array4[i])
    result.append(array5[i])

result 배열을 선언하고 array들의 0번째 인덱스부터 14번째까지 차례로 result 배열에 넣어주었다.

그리고 공백을 제거하기 위해 조건문을 사용하였다.

filtered_result = []

for char in result:
    if char != "":  # 빈 문자열 제거
        filtered_result.append(char)

result = filtered_result

필요 없었다 위 과정.
그 동안의 나는 print(*result) 이런식으로 바로 raw 출력해서 몰랐는데
리스트안에 콤마로 구분되어있는 문자들은
'구분자'.join(리스트) 를 활용하여 출력할 수 있었다.

words = ["abc","def","ghi"]
print("".join(words)) # : "abcdefghi" 출력

하나의 특징이

data = ["a", "b", "", "c", ""]
result = "".join(data)  # 기본적으로 공백 제거
print(result)  # abc

공백이 제거되며 나오기 때문에 해당 문제에 적합했다.
앞으로도 뭔가 (*result) 말고 join을 활용하는 것이 더 좋아보인다.

전체 코드

arrays = []

for i in range(5):
       string = input()
       array = list(string) + [""] * (15 - len(string))
       arrays.append(array)

array1,array2,array3,array4,array5 = arrays

result = []

for i in range(15):
    result.append(array1[i])
    result.append(array2[i])
    result.append(array3[i])
    result.append(array4[i])
    result.append(array5[i])

print("".join(result))

2563번: 색종이

드디어 코드를 바로 짜지 않고 어떻게 짤지 생각을 하고 풀어야하는 문제가 나왔다.
어떻게 풀지 생각을 해보았는데
겹치는 부분을 전체 넓이(300) 에서 빼는 것이 관건인 것 같다.

  • 그렇다면 겹치는 부분을 어떻게 구할 것 인가?

어떻게 되면 정사각형이 '겹치는 상태'가 될까?

입력 값에 주어지는 두 숫자는 정사각형의 왼쪽아래 꼭짓점의 좌표이다.
거기에 +10, +10 한 값은 정사각형의 오른쪽 위 꼭짓점의 좌표이다.

...
하다가 도저히 겹치는 부분의 넓이를 구하는 로직을 모르겠어서 GPT 사용했다.

  • GPT4o의 풀이
  1. 도화지를 2차원 배열로 모델링.
  2. 색종이가 덮는 영역을 1로 표시.
  3. 배열에서 값이 1인 셀의 개수를 세어 넓이를 계산.

여기서 모델링이란!
"모델링"이란?
모델링(modeling)은 현실 세계의 문제나 상황을 컴퓨터가 이해하고 처리할 수 있는 데이터 구조나 논리로 변환하는 과정을 말해. 이 문제에서는 "도화지"라는 현실의 2차원 평면을 컴퓨터가 다룰 수 있도록 2차원 배열로 표현하는 것을 "모델링"이라고 해.

#도화지 크기 : 100x100 2차원 배열
paper = [[0]*100 for _ in range(100)] 

print(paper)
#색종이 개수 입력
n = int(input())

#색종이 정보 입력 및 도화지 반영
for _ in range(n):
       x,y = map(int,input().split()) #색종이의 왼쪽 아래 좌표
       for i in range(x,x+10):
              for j in range(y,y+10):
                     paper[i][j] = 1


# 1로 색칠된 영역 넓이 계산
result = 0  # 검은 영역 넓이를 저장할 변수 초기화

# paper의 각 행(row)을 순회
for row in paper:
    # 현재 행(row)의 합계를 계산하고 result에 더함
    row_sum = sum(row)  # 한 행의 값의 합계
    result += row_sum
print(result)

느낀 점 : 처음 이런 활용 문제를 풀려고 시도해보았는데 확실히 그냥 코드구현 문제보다 생각하는 데 걸리는 시간이 현저히 높아서 재밌었고 동시에 더 스트레스받았고 더 풀고 싶었다. 더 잘해지고 싶다는 욕망이 생겼다. 역시 고통받아야 더 성장하는 것 같다.

작성하면서 든 생각.
줄줄줄 일기형식으로 쓰지 말고.
핵심만 딱. 보는 사람의 관점에서 읽기 쉽게.

profile
Frontend Engineers

0개의 댓글