[Algorithm] 백준_16924번: 십자가 찾기
업데이트:
오늘의 문제는 🚀 백준_16924번: 십자가 찾기이다.
..주말을 즐기다가 오늘안에 해결하지 못했다. 껄껄
그리고 문제 자체가 어려운 것도 한몫 한다…😂
테스트케이스 이해하기
위의 그림 처럼 *로 만들어진 십자가를 주어진 Input에서 찾는 문제이다.
결과값은 input에서 총 3개의 십자가를 찾을 수 있다는 것이다!
- (3,4)에 길이가 1인 십자가
- (3,5)에 길이가 2인 십자가
- (3,5)에 길이가 1인 십자가
위와 같이 십자가를 찾아내서 총 갯수와 좌표, 길이를 차례대로 프린트 해주면 된다.
1차 시도 : 실패
오늘 시도는 예외점이 많아서… 다른 방법을 찾아야할 것 같다.
- 알고리즘
- 이중포문을 돌려서 각각의 값에 접근 (가장 자리 1을 제외)
- *일 경우, for을 이용해서 왼쪽, 오른쪽, 위에, 아래를 확인해서 다 *일 경우 result에 i,j,길이 추가
- 길이를 늘려서 다시 확인해서 맞을 경우, result에 추가.
- result의 길이가 0이면 -1을 아니면, 내용물을 프린트
- 문제점
- 백준에 나와있는 예제 3번의 경우를 처리하지 못함.
- 십자가 중간에 구멍이 나있을 경우 처리 못함
- 시간 복잡도가 높음
- 총체적난국…!
- 다른 방법을 생각해야하는데 다 돌아다니면서 체크하는거 밖에 안떠오른다 흑흑😂
-
시도 코드
#입력 n,m = map(int, input().split()) arr=[list(map(str,list(input()))) for _ in range(n)] result=[] max = max(n,m) dx=[1,-1,0,0] dy=[0,0,1,-1] for i in range(1,n-1): for j in range(1,m-1): if arr[i][j] == "*": count = 1 while count < max: circle = 0 for k in range(4): i += dx[k]*count #길이 늘어나는 것 체크 j += dy[k]*count if -1 < i < n and -1 < j < m: if arr[i][j] == "*": circle += 1 i -= dx[k]*count j -= dy[k]*count if circle == 4: #십자가가 될 경우만 넣어 줌 result.append([i+1, j+1, count]) count += 1 if len(result) == 0: print(-1) else: print(result)
2차 시도 : 성공
아무리 생각해도 다 확인해보는거 말고는 생각이나지 않는다.
그래서 그냥 그대로 하고, 빈어레이를 만들어서 똑같이 만든후 확인하는 방식으르 더했다!
그랬더니 성공!
- 알고리즘
- 이중포문을 돌려서 각각의 값에 접근 (가장 자리 1을 제외)
- *일 경우, for을 이용해서 왼쪽, 오른쪽, 위에, 아래를 확인해서 다 *일 경우 result에 i,j,길이 추가
- 길이를 늘려서 다시 확인해서 맞을 경우, result에 추가. 안맞을 경우 break로 탈출
- result의 내용물 꺼내서 input과 똑같이 만들어서 check 어레이를 만듦.
- input과 check를 비교
- 같으면 결과값 출력, 아니면 -1출력.
정답 코드
n,m = map(int, input().split())
arr=[list(map(str,list(input()))) for _ in range(n)]
check=[["."]*m for _ in range(n)]
result=[]
max = max(n,m)
dx=[1,-1,0,0]
dy=[0,0,1,-1]
#십자가 찾기
for i in range(1,n-1):
for j in range(1,m-1):
if arr[i][j] == "*":
count = 1
while count < max:
circle = 0
for k in range(4):
i += dx[k]*count
j += dy[k]*count
if -1 < i < n and -1 < j < m:
if arr[i][j] == "*":
circle += 1
i -= dx[k]*count
j -= dy[k]*count
if circle == 4:
result.append([i+1, j+1, count])
else:
break
count += 1
#결과값으로 check 어레이 만들기
for i in range(len(result)):
x =result[i][0]-1
y =result[i][1]-1
count = result[i][2] +1
check[x][y] = "*"
for j in range(1, count):
for k in range(4):
x += dx[k] * j
y += dy[k] * j
check[x][y] = "*"
x -= dx[k] * j
y -= dy[k] * j
#두 어레이가 같은지 확인하기
printResult = True
for i in range(n):
for j in range(m):
if arr[i][j] != check[i][j]:
printResult = False
break
#결과 프린트 하기
if printResult:
print(len(result))
# 정렬은 선택
result.sort(key=lambda x: (x[0], x[1],-x[2]))
for i in range(len(result)):
print(' '.join(map(str, result[i])))
else:
print(-1)
🚀Reference: 백준_16924번 - 십자가 찾기