본문 바로가기

CS/알고리즘

백준 20125번 파이썬 : 쿠키의 신체 측정

실버4라기엔 조금 어렵지 않나 싶었던 문제

시간 초과 해결을 못해 한참 헤맸다

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

 

 

머리는 맨 위 한칸. 심장은 머리 바로 아래 빨간색.

허리, 좌우팔, 좌우다리의 길이는 1이상. 너비는 무조건 1. 

심장 위치와 팔, 다리, 허리 각 길이 반환해야 하는 문제

 

맨 위 머리를 좌표 (a,b)라 하면

심장은 (a+1, b)

왼팔 길이는 (a+1, b-1)부터 *끝날때까지 왼쪽 방향으로 개수 count++

오른팔 길이는 (a+1, b+1)부터 *끝날때까지 오른쪽 방향으로 개수 count++

허리는 (a+2, b)부터 *끝날때까지 아래 방향으로 개수 count++ (생각해보니 머리 열 좌표 찾아 길이 구하고 머리와 심장 길이만큼 -2하면 될 것 같아 비교적 간단하게 구함)

 

왼다리는 (a+3, b-1)부터 아래 방향으로 개수 count++

오른다리는 (a+3, b+1)부터 아래 방향으로 개수 count++

 

import sys
la, ra, waist, ll, rl=0,0,0,0,0 #왼팔, 오른팔, 허리, 왼다리, 오른다리 길이
mfound=False #머리발견여부
cenlen=0
N=int(input()) #판의 변의 길이
board= [input() for _ in range(N)]
"""
---
---
---
['---', '---', '---']
의 형태로 받음
"""

for i in range(N):
    for j in range(N):
        if board[i][j] == '*' and mfound==False:
            head=[i,j] #머리 위치 저장
            heart = [i+1,j]
            hearti=i+1
            heartj=j
            pheart=[i+2,j+1]
            mfound=True
            break
    if(mfound==True):
        break
        
print(*pheart)
 
for a in range(N):
    for b in range(N):
        if a==hearti and board[a][b]=='*': #왼팔 또는 오른팔
            if b<heartj:
                la+=1
            elif b>heartj:
                ra+=1
        if b==heartj and board[a][b]=='*': #심장이위치한 열에서 2만큼 빼면 허리길이
            cenlen+=1
        if b==heartj-1 and board[a][b]=='*':
            ll+=1
        if b==heartj+1 and board[a][b]=='*':
            rl+=1

ll-=1
rl-=1
         
waist=cenlen-2
print(la,ra,waist,ll,rl)

 

 

 

 


처음에 머리행 머리열 심장행 심장열 구해서 풀면 되나? 했더니

 

시간 초과났다

 

아래는 오류 코드

import sys
la, ra, w, ll, rl=0,0,0,0,0 #왼팔, 오른팔, 허리, 왼다리, 오른다리 길이
middlelen=0
mfound=False #머리발견여부

N=int(sys.stdin.readline()) #판의 변의 길이
board=[[0 for col in range(N+1)] for row in range(N+1)]

for i in range(1,N+1):
    for j in range(1,N+1):
        k=sys.stdin.readline() #좌표 하나
        board[i][j]=k
        if (k=='*' and mfound==False ):
            mi=i #머리행
            mj=j #머리열
            si=i+1 #심장행
            sj=j+1 #심장열
            
            mfound=True
            
for i in range(len(board)):
    for j in range(len(board)):
        if (j==mi and board[i][j]=='*'):
            middlelen+=1 #파이썬에는 증감연산자++없다 주의
        w=middlelen-2
        if(i==si and board[i][j]=='*'):
            if(j<sj):
                la+=1 #왼팔길이
            elif(j>sj):
                ra+=1 #오른팔길이
        if(j==mj-1 and board[i][j]=='*'):
            ll+=1
        ll-=1
        if(j==mj+1 and board[i][j]=='*'):
            rl+=1
        rl-=1
print(si,sj)
print(la,ra,w,ll,rl)

 

 

 

그리고 아래와 같이 짜면 cenlen에 해당하는 몸통 부분에서 심장이 빠지게 되어

허리의 수가 하나 줄어 잘못나옴

왼다리, 오른다리의 수도 하나 줄어들어 잘못나오는데 왜인지.. 생각해봐야겠다

이유 아시는 분은 댓글에 달아주시면 감사하겠습니다

 

import sys
la, ra, waist, ll, rl=0,0,0,0,0 #왼팔, 오른팔, 허리, 왼다리, 오른다리 길이
mfound=False #머리발견여부
cenlen=0
N=int(input()) #판의 변의 길이
board= [input() for _ in range(N)]
"""
---
---
---
['---', '---', '---']
의 형태로 받음
"""

for i in range(N):
    for j in range(N):
        if board[i][j] == '*' and mfound==False:
            head=[i,j] #머리 위치 저장
            heart = [i+1,j]
            hearti=i+1
            heartj=j
            pheart=[i+2,j+1]
            mfound=True
            break
    if(mfound==True):
        break
        
print(*pheart)
 
for a in range(N):
    for b in range(N):
        if a==hearti and board[a][b]=='*': #왼팔 또는 오른팔
            if b<heartj: #왼팔
                la+=1
            elif b>heartj: #오른팔
                ra+=1
        elif b==heartj and board[a][b]=='*': #심장이위치한 열에서 2만큼 빼면 허리길이
            cenlen+=1
        elif b==heartj-1 and board[a][b]=='*': #왼다리
            ll+=1
        elif b==heartj+1 and board[a][b]=='*': #오른다리
            rl+=1

ll-=1
rl-=1
         
waist=cenlen-2
print(la,ra,waist,ll,rl)