대각선으로 숫자 채우기


n * m크기의 직사각형에 숫자를 1부터 순서대로 1씩 증가시키며 왼쪽 위에서부터 시작하여 오른쪽 아래 쪽까지 다음과 같은 방향으로 숫자들을 쭉 채우는 코드를 작성해보세요.

 

 

 

 

입력 형식

n과 m이 공백을 사이에 두고 주어집니다.

  • 1 ≤ n, m ≤ 100

출력 형식

숫자로 채워진 완성된 형태의 n * m 크기의 사각형을 출력합니다.

(숫자끼리는 공백을 사이에 두고 출력합니다.)

 

예제1

입력:

3 3

 

출력:

1 2 4
3 5 7
6 8 9

 

 

내가 짠 코드

n, m = tuple(map(int, input().split()))
cnt = 1

arr_2d = [
    [0 for _ in range(m)]
    for _ in range(n)
]

cnt = n+m-2
val = 1

for i in range(cnt+1):
    a = 0
    b = i
    for j in range(i+1):
        if (a<n) & (b<m):
            arr_2d[a][b] = val
            val+=1
        a+=1
        b-=1
        
for row in range(n):
    for elem in range(m):
        print(arr_2d[row][elem] , end= " ")
    print()

 

우선 n, m 에 tuple(map(int, input().split())를 통해 공백을 기준으로 잘라서 인트형으로 변환시켜서 변수에 넣는다.

그 후 n행 m 열의 배열을 선언한다.

 

이차원 배열에서 가장 중요한 것은 반복횟수를 결정하는 것이댜.

 

2차원 배열에선 가장 큰틀과 작은 틀을 알아차릴 수 있어야한다.

반복문안에 반복문을 실행해야 하므로 

큰 반복이 뭐고 그 안에 들어갈 작은 반복이 무엇인지 관찰을 통해 알아내야 한다.

 

여기서는

예를들어 입력으로

3 3 이들어왔을때

참조되는 배열의 인덱스가

 

00 / 01 10 / 02 11 20 / 03 12 21 30 / 04 13 22 31 40

 

의 순서대로 이다.

arr_2d[0][0] -> arr_2d[0][1] -> arr_2d[1][0] -> arr_2d[0][1] -> arr_2d[0][2] ->  ... -> arr_2d[4][0] 순서대로 참조가 필요하다는 의미이다.

 

어디까지 반복을 해야할지는 전체 규칙을 확인해보자

00 / 01 10 / 02 11 20 / 03 12 21 30 / 04 13 22 31 40

에서 마지막에 등장해야하는 인덱스는 3 3 배열에서는 [2,2] 일때 이다. 

이 숫자가 의미하는 것을 알아보자면 행과 열의 인덱스 합과 관련이 있다. 

 

이 문제에서는 2차원배열에서 행과 열의 인덱스합이 최고인 때까지 순회해야한다.

 

따라서 3 3 이라는 예시에서는 최고 인덱스가 (2, 2) 이다. 이 합은 4가 된다.

 

일반화하면 최고 인덱스는 [(입력받은 행수 -1), (입력받은 열수 -1)] 라는 것을 알수있다.

그러므로 이 둘의 합은 n+m-2 로 나타낼 수 있으며

반복해서 참조할때는

0 0 까지 포함시켜야하므로 n+m-2 에다가 +1을 해서

큰 반복은 n+m-1 번 반복해야한다.

 

00 / 01 10 / 02 11 20 / 03 12 21 30 / 04 13 22 31 40

 

위 예시에서 이제 작은 반복(반복문 속 반복문)을 보자

첫번째에서는 1번

두번째에서는 2번

3번째에서는 3번

4번째에서는 4번

5번째에서는 5번의 

반복을 진행하는 것으로보아 

 

i번째에는 i번 반복하도록 코드를 짜면된다(인덱스에 주의 !)

 

cnt = n+m-2
val = 1

for i in range(cnt+1):
a = 0
b = i
for j in range(i+1):
if (a<n) & (b<m):
arr_2d[a][b] = val
val+=1
a+=1
b-=1
 
우선 n+m-1번의 반복을 진행하는데 
a = 0 b = i 번으로 초기화 시킨다.
ㅁ번째는 ㅁ번 반복해야한다.
 
0이 들어가면 반복되지 않게되므로
0을 카운트해준 i+1을 써준다.
 
i번의 반복을 위해 range에 i+1 을 입력시킨다.
 
그리고 val 값을 증가시키며 값에 넣어주는데 이때 중요한 점은 인덱스를 넘어가면 배열 참조가 불가능하므로 a는 행의 최고 인덱스를 넘어서는 안되고 b 는 열의 최고 인덱스를 넘어서는 안된다.
 
분기문으로 이를 처리해준다.
 
 
 
 
 
 
 

 

728x90

+ Recent posts