Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 네트워크
- 쉬운 코드
- 시스템프로그래밍
- 백엔드
- 코딩애플
- 운영체제
- 반효경
- 시그널 핸들러
- recoverability
- 개발남노씨
- 온디바이스AI
- Extendable hashing
- BreadcrumbsComputer-Networking_A-Top-Down-Approach
- concurrency control
- SDK
- Git
- 프로세스 주소 공간
- 운영체제와 정보기술의 원리
- 인터럽트
- 커널 동기화
- 김영한
- 트랜잭션
- 코딩테스트 [ ALL IN ONE ]
- B tree 데이터삽입
- 갤럭시 S24
- vite
- 데이터베이스
- CPU 스케줄링
- SQL
- 쉬운코드
Archives
- Today
- Total
티끌모아 태산
21610: 마법사 상어와 비바라기 본문
728x90
https://www.acmicpc.net/problem/21610
21610번: 마법사 상어와 비바라기
마법사 상어는 파이어볼, 토네이도, 파이어스톰, 물복사버그 마법을 할 수 있다. 오늘 새로 배운 마법은 비바라기이다. 비바라기를 시전하면 하늘에 비구름을 만들 수 있다. 오늘은 비바라기
www.acmicpc.net
설명
삼성전자 기출 문제로 8가지 방향을 고려하는 구현 문제이다. 그리고 이어진 격자 즉, 배열이 이어져 있다는 뜻. 배열의 마지막 원소의 다음 원소는 첫 번째 원소가 된다. 따라서 구름을 d방향으로 s만큼 이동하는 경우 다음과 같이 모듈러 연산(%)를 이용하여 적절한 위치로 이동해야 한다.
nx = (x + dx8[d-1] * s) % n
ny = (y + dy8[d-1] * s) % n
그리고 물복사 버그에서의 격자 경계를 고려해야한다. 즉, 아래에서 "이때는 이동과 다르게 경계를 넘어가는 칸은 대각선 방향으로 거리가 1인 칸이 아니다." 이 부분을 고려해여 한다. 따라서 이 경우에는 구름이 이동할 때와 달리 다음과 같이 예외처리를 해줘야한다.
# 대각선 방향 정의
dx4 = [-1,-1,1,1]
dy4 = [-1,1,-1,1]
for cloud in next_clouds:
x, y = cloud[0], cloud[1]
# 물이 있는 즉, graph[x][y] >= 1 인 바구니의 수를 센다
count = 0
for i in range(4):
nx = x + dx4[i]
ny = y + dy4[i]
if (0 <= nx < n) and (0 <= ny < n) and graph[nx][ny] >= 1:
count += 1
graph[x][y] += count # 바구니의 수만큼 물의 양을 증가 시킨다.
핵심 아이디어
dx8 = [0, -1, -1, -1, 0, 1, 1, 1]
dy8 = [-1, -1, 0, 1, 1, 1, 0, -1]
- 문제에서 제시한 방향대로 구현하는 전형적인 시뮬레이션 문제.
코드 구현
n, m = map(int, input().split())
graph = []
for _ in range(n):
graph.append(list(map(int, input().split())))
# 비바라기 시전했을 때 생기는 비구름 좌표
clouds = [(n-1, 0), (n-1, 1), (n-2, 0), (n-2, 1)]
# 구름이 이동하는 8가지 방향 정의
dx8 = [0, -1, -1, -1, 0, 1, 1, 1]
dy8 = [-1, -1, 0, 1, 1, 1, 0, -1]
for _ in range(m): # m회 실행
d, s = map(int, input().split())
next_clouds = [] # 비구름 이동후 좌표
visited = [[False] * n for _ in range(n)] # 이동해서 물 내렸는지
# 1. d방향으로 s만큼 이동 후 이동 좌표를 next_clouds 에 담는다.
for cloud in clouds:
x, y = cloud[0], cloud[1] # 비구름 좌표
nx = (x + dx8[d-1] * s) % n # 1번행과 n번행이 이어져 있음
ny = (y + dy8[d-1] * s) % n # 1번열과 n번열이 이어져 있음
next_clouds.append((nx,ny))
# 2. 비내리기
for cloud in next_clouds:
x,y = cloud[0], cloud[1]
graph[x][y] += 1 # 비구름이 있는 바구니의 물의양 1 증가시키기
visited[x][y] = True # 방문처리-> 물의 양 1 증가 여부
# 3. 구름 제거
clouds = []
# 4. next_clouds에 있는 칸에서 대각선 방향으로 1 거리의 칸에서
# 물의 양이 바구니의 수만큼 증가
# 단, 이때는 대각선 방향으로 1번열 & n번열 이어지지 않는다.
# 대각선 방향 정의
dx4 = [-1,-1,1,1]
dy4 = [-1,1,-1,1]
for cloud in next_clouds:
x,y = cloud[0], cloud[1]
# '물이 있는 즉, graph[x][y] >= 1 바구니의 수를 센다'
count = 0
for i in range(4):
nx = x + dx4[i]
ny = y + dy4[i]
if (0 <= nx < n) and (0 <= ny < n) and graph[nx][ny] >= 1:
count += 1
graph[x][y] += count # 바구니의 수만큼 물의양을 증가 시킨다.
# 5. 물의 양이 2 이상인 칸에 구름 생성 하기
for i in range(n):
for j in range(n):
# 3에서 구름이 사지진 칸이 아니라는 것 -> 방문한적이 없는 칸
if graph[i][j] >= 2 and visited[i][j] == False:
#바구니에 저장된 물의 양이 2 이상인 모든 칸에 "구름이 생기고"
# 여기서는 물의 양이 1 증가 한 것이 아니기 때문에 True 안해도됨!
clouds.append((i,j))
# 물의 양이 2 줄어든다.
graph[i][j] -= 2
ans = 0
for i in range(n): # 모든 행에 대하여
ans += sum(graph[i])
print(ans)
728x90
'백준 문제 > 삼성 기출' 카테고리의 다른 글
20056: 마법사 상어와 파이어볼 (0) | 2024.03.02 |
---|---|
14503: 로봇 청소기 (0) | 2024.03.01 |
20055: 컨베이어 벨트 위의 로봇 (0) | 2024.03.01 |