ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Python] 백준 16924번 십자가 찾기
    코팅테스트 연습/파이썬 2021. 11. 23. 17:44

     

    십자가 찾기 

    시간 제한메모리 제한제출정답맞힌 사람정답 비율
    2 초 512 MB 1432 562 415 38.858%

    문제

    십자가는 가운데에 '*'가 있고, 상하좌우 방향으로 모두 같은 길이의 '*'가 있는 모양이다. 십자가의 크기는 가운데를 중심으로 상하좌우 방향으로 있는 '*'의 개수이다. 십자가의 크기는 1보다 크거나 같아야 한다.

    아래 그림은 크기가 1, 2, 3인 십자가이고, 빈 칸은 '.'이다.

                  ...*...
          ..*..   ...*...
    .*.   ..*..   ...*...
    ***   *****   *******
    .*.   ..*..   ...*...
          ..*..   ...*...
                  ...*...

    크기가 N×M이고, '.'과 '*'로 이루어진 격자판이 주어진다. 이때, 십자가만을 이용해서 격자판과 같은 모양을 만들 수 있는지 구해보자. 십자가는 서로 겹쳐도 된다. 사용할 수 있는 십자가의 개수는 N×M이하이어야 한다. 격자판의 행은 위에서부터 1번, 열은 왼쪽에서부터 1번으로 번호가 매겨져 있다.

    입력

    첫째 줄에 격자판의 크기 N, M (3 ≤ N, M ≤ 100)이 주어진다. 둘째 줄부터 N개의 줄에 격자판의 상태가 주어진다.

    출력

    십자가만 이용해서 입력으로 주어진 격자판을 만들 수 없으면 -1을 출력한다.

    만들 수 있는 경우에는 필요한 십자가의 수 k(0 ≤ k ≤ N×M)를 출력한다. 다음 k개의 줄에는 그려야 하는 십자가의 정보 x, y, s를 한 줄에 하나씩 출력한다. x는 십자가 중심의 행의 번호, y는 열의 번호, s는 십자가의 크기이다.

    가능한 답이 여러가지인 경우에는 아무거나 출력한다.

    예제 입력 1 복사

    6 8
    ....*...
    ...**...
    ..*****.
    ...**...
    ....*...
    ........
    

    예제 출력 1 복사

    3
    3 4 1
    3 5 2
    3 5 1
    

    예제 입력 2 복사

    5 5
    .*...
    ****.
    .****
    ..**.
    .....
    

    예제 출력 2 복사

    3
    2 2 1
    3 3 1
    3 4 1
    

    예제 입력 3 복사

    5 5
    .*...
    ***..
    .*...
    .*...
    .....
    

    예제 출력 3 복사

    -1
    

    예제 입력 4 복사

    3 3
    *.*
    .*.
    *.*
    

    예제 출력 4 복사

    -1

     

     


    풀이방법

    • 입력받은 예제를 2차원 리스트로 만들어 inputList 에 저장합니다
    • inputList 를 resultList(십자가를 지울 리스트) 에 딥카피를 이용 복사합니다
    • inputList 의 위에서부터 '*' 을 찾아 상하좌우를 검사해 십자가를 찾고 십자가를 찾았을때는 resultList 에 십자가를 지워 줍니다
    • 끝까지 다 검사했을때 십자가를 지운 리스트에 '*' 가 존재하는지 검사해 주고 존재할시 -1 아니면 count 갯수와 result 리스트를 출력해 줍니다

     

    코드


     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    import sys
    import copy
     
    a,b =map(int , sys.stdin.readline().split()) # 세로와 가로를 입력받음
    inputList = [] #이차원배열을 넣을 리스트
    for i in range(a):
        inputList.append(list(sys.stdin.readline().strip())) #리스트를 입력받아 삽입
     
    finalList =copy.deepcopy(inputList) #딥카피를 통해 십자가를 그렸을경우 "*" 에서 "." 으로 바꿀 그래프를 만든다
    count =0 # 십자가의 갯수
    result =[] #(세로 , 가로 , 사이즈) 형태의 답을 넣을 리스트
    for i in range(1, a):
        for j in range(1,b): #맨윗줄부터 아랫줄로 이어지는 for문
            size = 0 #사이즈를 초기화
            if (inputList[i][j]=='*'): #받은 리스트 에  '*' 이 존재할시
                up=down =i
                left=right=j
                #현재 위치를 저장
     
                while(1): # 십자가가 없을때까지 루프
                    up= up-1 #상하좌우 좌표를 가져옴
                    down =down+1
                    left = left-1
                    right = right+1
     
                    if(up>=0 and down<and left>=0 and right<and inputList[up][j] =='*' and inputList[down][j] =='*'and inputList[i][left] =='*' and inputList[i][right] =='*' ):
                        #상하좌우가 리스트의 크기를 넘어가지 않고 '*' 일때
                        finalList[up][j] =finalList[down][j] =finalList[i][left] =finalList[i][right]=finalList[i][j] ='.' # 십자가를 그렸음으로 십자가의 위치 값을 '*' 에서 '.' 으로 바꿔준다
                        size = size + 1 #사이즈 상승  그후
                    else#더이상 십자가가 없을때
                        if(size>0): #사이즈가 0보다 클때 즉  1이상의 크기를 가진 십자가를 현재 위치에서 찾을 수 있을때
                            result.append("{0} {1} {2}".format(i+1 ,j+1,size)) #result 리스트에 (세로 , 가로 , 사이즈) 형태로 삽입한다
                        break
            if(size !=0): #사이즈가 0이 아닐때 즉 하나의 십자가를 찾았을때 count 값을 추가해준다
                count =count+1
    check = True # 십자가를 그린 리스트 finalList 에 '*' 이 존재 하는지 확인하기 위한 boolean 값
    for i in finalList:
        if '*'in i:
            print(-1)
            check=False #십자가를 다그렸음에도 '*' 가 남아있는경우 에는 False 값을 주고 -1 을 출력한다
            break
    if(check):
        print(count) #십자가를 다그려 '*' 가 남아있지않은경우 십자가의 갯수와 result 리스트를 출력한다
        for i in result:
            print(str(i))
     
    cs

    댓글

Designed by Tistory.