Notice
Recent Posts
Recent Comments
Link
꾸준하게 거북이처럼
[코드트리 챌린지] 3주차 - 미로 타워 디펜스 본문
3주차 진단 결과
요즘 그래프탐색, 구현만 준비 중이라,, ㅎㅎ
문제풀이
코드트리 | 코딩테스트 준비를 위한 알고리즘 정석
국가대표가 만든 코딩 공부의 가이드북 코딩 왕초보부터 꿈의 직장 코테 합격까지, 국가대표가 엄선한 커리큘럼으로 준비해보세요.
www.codetree.ai
문제
한 라운드 당 다음과 같은 연산 수행
1. 상하좌우 방향 중 공격 칸 수 만큼 몬스터 공격해서 없애기
2. 빈공간 만큼 앞으로 이동시킴
3. 종류가 같은 몬스터 번호가 연속 4개이상이면 삭제
4. 다시 빈공간 만큼 앞으로 이동 시킴 => 연속 4개이상이 없을 때 까지 3&4번 반복.
5. 중심부터 (0,0)까지 쭉 나열 했을 때, (총 개수, 숫자크기) 순서로 그룹화한 숫자를 다시 배열에 할당. 단, 격자범위 넘으면 그 이후는 무시.
* 1번과, 3번에서 삭제된 각 (몬스터 번호* 삭제된 개수) 들의 합 구하기*
코드
n,m = map(int,input().split())
g = []
for _ in range(n):
g.append(list(map(int,input().split())))
sx,sy = n//2,n//2# 중심 좌표. 가운데.
num = [[0]*n for _ in range(n)]# 각 좌표에서의 monster 배열의 인덱스를 담을 배열.
answer = [0,0,0] # 1,2,3 번 몬스터 각각 제거된 개수를 담을 배열.
monster =[]
dx = [0,1,0,-1]# d,p를 입력 받을 때, 방향대로 지정(우 하 좌 상)
dy = [1,0,-1,0]
# 달팽이 모양 대로 중심부터 (0,0)좌표 까지 방향을 순서대로 나타낸 배열. 좌 하 우 상
mx = [0,1,0,-1]
my = [-1,0,1,0]
# num[x][y]는 monster의 인덱스 역할을 함.
def init():# 입력 받은 배열을 일자로 뒀을 때 모양을 monster에 할당하기, num 배열에 각 좌표에서 monster의 인덱스를 할당.
global monster,num
x,y=n//2,n//2
cnt = 0
di = 0
idx = 0
while 0<=x <n and 0<=y < n:# 범위를 벗어나면 종료.
if di % 2 == 0:# 1 1 2 2 3 3 ,, (몇 칸씩 좌 하 우 상 방향 대로 나아감.) 방향이 짝수 인덱스 일 때, cnt 증가.
cnt += 1
for _ in range(cnt):
x += mx[di]
y += my[di]
if 0 <= x <n and 0 <= y < n:
monster.append(g[x][y])
num[x][y] = idx # 인덱스 할당.
idx +=1
else:
break
di = (di+1)%4
def remove():# d방향 p칸 만큼 제거.
global monster, answer
x,y = sx,sy
for _ in range(p):
x += dx[d]
y += dy[d]
if 0 <= x < n and 0 <= y < n:
idx = num[x][y]
v = monster[idx]
monster[idx] = 0
if v > 0:# ***** 만약 해당 칸의 값이 0이라면, 점수에 해당 하지 않는 부분(1,2,3만 구함) 이므로 유의해야함.*****
answer[v-1] += 1
else:
break
def org():# 비워진 부분 제외하고 다시 새로 배열을 만든다. (비워진 부분을 앞으로 당긴다.)
global monster
tmp = []
length = len(monster)
for v in monster:
if v!=0:
tmp.append(v)
tmp.extend([0]*(length-len(tmp)))
monster = tmp
def sameRemove():# 연속 4개이상이면 없애기.
global monster, answer
flag = False
cnt= 0
prev = monster[0]
start = 0
for i in range(len(monster)):
if monster[i]==0:# 0은 제외!**
break
if prev == monster[i]:
cnt += 1
else:
if cnt >=4:
flag = True
answer[prev-1] += cnt
for j in range(start,i):# 연속적인 부분은 0으로 할당.
monster[j] = 0
start = i# 다음 연속 부분의 시작 인덱스를 담기.
cnt = 1# 개수 세기 다시 1로.
prev=monster[i]# 현재 비교하고자 하는 숫자 할당.
if cnt >=4:
flag = True
answer[prev-1] += cnt
for j in range(start,len(monster)):
monster[j] = 0
return flag
def change():# 그룹화 하기 ( 개수, 숫자 크기)형식. 만약 격자범위를 넘으면 자르기.
global monster
tmp = []
prev = monster[0]
cnt = 0
for i in range(len(monster)):
if monster[i] == prev:
cnt += 1
else:
tmp.append(cnt)
tmp.append(prev)
cnt = 1
prev = monster[i]
if monster[i] ==0:# 0이라면 더이상 세지 않아도 됨.
break
else:
tmp.append(cnt)
tmp.append(prev)
if len(tmp) >= n*n:# 범위 넘어서면 자르기.
monster =tmp[:len(monster)]
else:# 부족한 0부분 채우기.
tmp.extend([0]*(len(monster)- len(tmp)))
monster = tmp
init()# 초기화
for i in range(1,m+1):
d,p = map(int,input().split())
remove()# p칸만큼, d방향으로 삭제
org()# 앞으로 댕기기
while sameRemove():# 4개이상 같으면 제거
org()# 다시 앞으로 당기기
change()# 개수, 숫자 크기 형태로 그룹화하기.
point = 0
for i,v in enumerate(answer):
point += ((i+1)*v)
print(point)
# 삼성 기출 코드트리.
** 실수 체크: 주어진 방향으로 제거할 때, 점수 체크하는 부분에서 0은 점수에 해당하지 않음에 유의!! **
'Algorithm 문제 & 공부 > 챌린지' 카테고리의 다른 글
[코드트리 챌린지] 7주차 - 문자열 비교 (0) | 2023.10.23 |
---|---|
[코드트리 챌린지] 5주차 - 코드트리빵 (1) | 2023.10.09 |
[코드트리 챌린지] 4주차 - 불안한 무빙워크 (1) | 2023.10.02 |
[코드트리 챌린지] 2주차 - 술래잡기 (0) | 2023.09.18 |
[코드트리 챌린지] 1주차 - 메이즈러너 (0) | 2023.09.05 |
Comments