ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [코드업 기초 100제 1098번] 설탕과자 뽑기 풀이
    Coding Test/Algorithm 2019. 8. 21. 15:00

    잉~어! 잉~어!ㅇ ㅣ이이이잉어! 이이이이잉 앗쌀라말라쿰

     

     

    코드업을 풀다보면 도대체 이 경곽이는 어떤놈이길래 이러나 경곽이에 대한 미운정이 들기 시작한다.

     

    100문제 중 대망에 마지막 문제를 풀기전 마지막 관문인 98번 문제에 대해서는 풀이를 남겨보려고 한다.

     

     

    [문제 설명]

    아버지와 함께 유원지에 놀러간 경곽이는 설탕과자(설탕을 녹여 물고기 등의 모양을 만든 것) 뽑기를 보게 되었다.

    길이가 다른 몇 개의 막대를 바둑판과 같은 격자 판에 놓는데,

    격자 판에 적혀있는 설탕과자 이름(잉어, 붕어, 용 등 여러 가지가 가로 또는 세로로 연달아 적혀있다.)을 가리면,

    그 설탕과자를 가져가는 사행성? 게임이었다.

    가장 큰 설탕과자를 따볼까? 생각한 경곽이는

    격자판에 막대기를 놓는 모든 방법을 살펴본 후 가장 큰 설탕과자를 얻을 수 있는 방법을 알아내기 위해

    격자판에 막대기를 놓는 기본적인 상황을 바둑판에 바둑알 놓기처럼 만들어보고자 하였다.

    격자판의 세로(h), 가로(w), 막대의 개수(n)와 각 막대의 길이(l), 막대를 놓는 방향(d: 가로는 0, 세로는 1)과 막대를 놓는 막대의 가장 왼쪽 또는 위쪽의 위치(x, y)가 주어질 때, 격자판을 채운 막대의 모양을 출력하는 프로그램을 만들어보자.

     

    [입력]

    첫 줄에 격자판의 세로(h), 가로(w)가 공백을 두고 입력되고,

    두 번째 줄에 놓을 수 있는 막대의 개수(n), 각 막대의 길이(l), 방향(d), 좌표(x, y)가 입력된다.

    입력값의 정의역은 다음과 같다.

    1 <= w, h <= 100

    1 <= n <= 10

    d = 0 or 1

    1 <= x <= w

    1 <= y <= h

    단, 막대가 격자판을 벗어나는 경우는 입력되지 않는다.

     

    [출력]

    모든 막대를 놓은 격자판의 상태를 출력한다.

    막대에 의해 가려진 경우 1, 아닌 경우 0으로 출력한다.

     

     

    도움말이 없는 만큼 묻고답하기 란이 아주 난리가 나있는 문제였다.

     

    풀이이기 때문에 정답소스코드 보단 풀이 과정에 집중해서 포스팅해서 코딩을 함에 있어서 도움을 드리고자 한다.

     

    이런 문제는 문제가 쓸대 없이 길기 때문에 입출력 예시를 통해서 원리를 파악해야한다.

     

    입력 예시에서 주의해야 할 점이 있다.

    나도 처음에  

    """

    1 <= w, h <= 100

    1 <= n <= 10

    d = 0 or 1

    1 <= x <= w

    1 <= y <= h

    """

    라고 적혀있어서

    당연히 첫번째 입력값을 w로 만들었는데 오류가 났다.

    자세히 살펴보니까

     

     

    "격자판의 세로(h), 가로(w), 막대의 개수(n)와 각 막대의 길이(l), 막대를 놓는 방향(d: 가로는 0, 세로는 1)과 막대를 놓는 막대의 가장 왼쪽 또는 위쪽의 위치(x, y)가 주어질 때, 격자판을 채운 막대의 모양을 출력하는 프로그램을 만들어보자."

    이게 순서였다;;;

    이럴거면 잘 좀 써놓지;

     

    각설하고 보면

     

    1이 막대를 말하는 듯하다.

    막대길이만큼 1을 채우는데 가로 세로 방향에 따라서 x축을 채울지 y축을 채울지가 갈리며 입력 좌표에서 시작하도록 만드는 것이다.

    그럼 이제 시작해보자.

     

     

    우성 가장 먼저 코드를 작성해야 하는 부분은 당연히 입력받는 부분과

    잘 입력이 되었는지 출력하는 코드이다.

     

    이 입출력 부분부터 작성해보자

     

    참고로 필자는 파이썬을 이용하였다.

     

    입력 순서는

    h, w

    n

    l, d, w, y

     

    햇갈리지 않게 변수 이름을 맞춰 주었다.

     

    h, w = map(int, input().split())
    n = int(input())
    namu = []
    for i in range(0, n):
        buf = input().split()
        namu.append(buf)

     

    l, d, w, y는 나무라는 2차원 배열에 함께 입력을 해주었다.

    당연히 이 나무의 배열의 길이는 n번 돌기 때문에 포문에서 n번만큼 버퍼에 입력받아서 namu 리스트에 저장할 수 있도록 했다.

     

    98번까지 풀어오셨다면 파이썬을 이용하신 분들이라면 map을 쓴 이유는 아실것이고 append를 보고 넘어가자면

    기존 배열에 뒤에 새로 값을 추가해 주는 메서드이다. 이 입력값에는 배열이 들어와도 상관이 없다.

    그래서 배열을 입력해줌으로써 2차원 배열을 만들수가 있다.

     

    입력 값을 잘 받았는지 출력 하는 코드를 통해서 확인해보자.

    (당연히 잘 받겠지라는 생각에 바로바로 넘어가는 것은 좋지가 않다. 특히 파이썬에선 디버깅 모드가 딱히 없기 때문에 천천히 코드를 하나하나 완성해 감에 있어서 print를 통해서 내가 원하는 값이 잘 들어가고 있는지 확인하는 습관이 매우 중요하다.)

     

    print(namu)를 하면 이차원 배열 형태로 입력값이 잘 들어가 있다는 것을 확인 할수 있을 것이다.

     

    그럼 이제 출력을 해줄 2차원 배열을 생성해야 한다.

    이 배열은 당연 h, w 변수에 영향을 받는다.

     

    higth라는 배열을 만들고 width라는 버퍼를 만들어서 for문을 돌렸다.

    당연히 초기 값은 0으로 셋팅해주었다.

     

    higth = []
    for i in range(0, h):
        width = [0]
        width = width * w
        higth.append(width)

     

    포문을 h만큼 돌리게 되면 입력 받는 높이만큼 판이 만들어지며 0을 w만큼 추가해줌으로써 가로 길이도 맞추어 줄 수가 있다.

     

    이렇게 코드를 만들고 print(highth)를 실행해주면 배열이 잘 생성된 것을 확인 할수가 있다.

     

     

    그럼 이제 입력값도 다 받았겠다.

    출력할 배열도 생성했겠다.

    이 두가지를 이용하여서 출력할 배열을 수정하는 일만 남았다.

     

    다시 namu배열 얘기를 좀 더 해보겠다.

    여기서 한가지 주의해야 할 점은 buf는 map을 통해서 int형으로 받지 않았다.

    숫자가 들어있지만 str형태라는 것을 인지하고 코드를 짜야한다.

    그래서 좀 코드가 더러워졌지만 이런 방법을 사용했다.

     

    for i in range(0, n):
        l = namu[i][0]
        b = namu[i][1]
        x = namu[i][2]
        y = namu[i][3]
        l = int(l)
        x = int(x) - 1
        y = int(y) - 1
    
        while(l > 0):
            higth[x][y] = 1
            if b == '0':
                y += 1
            else:
                x += 1
            l = l - 1

     

    앞 부분이 매우 더럽다 ㅠㅠㅠ

    사실 l = int(namu[i][0])을 해보았지만 왜인지 오류가 뜬다.

    이 부분에 대해서는 아직 잘 모르겠다...

    옛말에 모르면 몸이 고생한다는 말이 있다.

    모르면 어쩔수가 없다 좀 더 코드를 길게 늘리면 된다... 위에 처럼..

     

    x와 y에 -1를 해준 이유는 입력받을 좌표가 1,1이면 배열에서는 0,0을 가리키기 때문에 -1을 해주었다.

    배열은 0 부터 시작하는 특징 때문에 그렇다.

     

    namu 배열의 길이는 n이기 때문에 당연히 for문은 n번만 돌렸고 그안에서 while문을 l번만큼 돌아가게 만들었다.

    사실 이중 for문써도 됩니다.(취향것...)

     

    (지금 알았는데 d를 b로 정의해주었네요 ㅎ)

     

    바깥 for문을 보면 for문이 돌때마다 l, b, w, y를 재정의해주며 while문에 들거가게 만들었다.

    그렇게 들어간 변수들을 통해서 while문에서 실질적인 편집이 이루어지게 되는 구조로 짰다.

    l의 길이 만큼 돌리기 위해서 l > 0을 조건으로 하고 한번 돌때마다 l-- 을 해주었다.

     

    for k in rnage(0, l):

    을 적어도 무관하다.

    아무튼 각설하고 보면

    b(방향 변수)가 0이냐 1이냐에 따라서 if else구문을 나누어서 x를 증가시킬지 y를 증가시킬지 정의했다.

    가로라면 당연히 y를 올리고 세로라면 x를 올리는 형식이다.

    이렇게 해서 수정을 마치고 출력하면 완성.

     

     

     

    출력문을 쓰지 않은 이유는..

    그저 복붙해서 긁어다가 쓰지 말라는 작은 바램이여서 그렇습니다. ㅎㅎ

    참고만 하시고 아이디어만 가져가주세요 ㅠㅠ

    직접 해볼때 자신의 것이 되니까요.

     

    댓글

Designed by Tistory.