https://www.acmicpc.net/problem/20057
20057번: 마법사 상어와 토네이도
마법사 상어가 토네이도를 배웠고, 오늘은 토네이도를 크기가 N×N인 격자로 나누어진 모래밭에서 연습하려고 한다. 위치 (r, c)는 격자의 r행 c열을 의미하고, A[r][c]는 (r, c)에 있는 모래의 양을
www.acmicpc.net
구현 문제다.
깊게 생각해야 할 부분은 없었고 문제대로 바로 구현했다.
방향이 바뀌는 점을 어떻게 처리해야 하는지 고민이었다.
4방향 좌(1) 하(2) 우(3) 상(4) 으로 나눠서 하나하나 구현했다.
방향이 변해도 흩어지는 비율은 같기 때문에 해당 배열은 한 번만 선언했다.
토네이도는 1칸 (방향전환) 1칸(방향전환) 2칸 (방향전환) 2칸 (방향전환) 3칸 ...
이런식으로 방향회전 두 번마다 이동 칸이 한 칸 씩 증가했다.
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
// 좌
int d1r[9] = { -2, -1, -1, -1, 0, 1, 1, 1, 2 };
int d1c[9] = { 0, -1, 0, 1, -2, -1, 0, 1, 0 };
// 하
int d2r[9] = { 0, 1, 0, -1, 2, 1, 0, -1, 0 };
int d2c[9] = { -2, -1, -1, -1, 0, 1, 1, 1, 2 };
// 우
int d3r[9] = { -2, -1, -1, -1, 0, 1, 1, 1, 2 };
int d3c[9] = { 0, 1, 0, -1, 2, 1, 0, -1, 0 };
// 상
int d4r[9] = { 0, -1, 0, 1, -2, -1, 0, 1, 0 };
int d4c[9] = { -2, -1, -1, -1, 0, 1, 1, 1, 2 };
// 비율
int ratio[9] = { 2, 10, 7, 1, 5, 10, 7, 1, 2 };
int board[500][500];
int main() {
// 입출력 속도를 단축시키기 위함
ios::sync_with_stdio(0);
cin.tie(0);
int N, r, c, d = 1, re = 0;
cin >> N;
for (int i = 1; i <= N; i++)
for (int j = 1; j <= N; j++) cin >> board[i][j];
// 토네이도 시작 값
r = c = N / 2 + 1;
for (int i = 1; i <= N; i++) {
for (int j = 0; j < 2; j++) {
for (int k = 0; k < i; k++) {
// 한 칸 이동
if (d == 1) c--;
else if (d == 2) r++;
else if (d == 3) c++;
else if (d == 4) r--;
int sand = board[r][c]; // 해당 칸 모래 저장
int sum = 0; // 흩어진 모래의 양 저장
board[r][c] = 0; // 토네이도가 도착한 칸은 모래가 사라짐
// 흩어지는 좌표 확인
for (int l = 0; l < 9; l++) {
int rr, cc;
if (d == 1) {
rr = r + d1r[l];
cc = c + d1c[l];
}
else if (d == 2) {
rr = r + d2r[l];
cc = c + d2c[l];
}
else if (d == 3) {
rr = r + d3r[l];
cc = c + d3c[l];
}
else if (d == 4) {
rr = r + d4r[l];
cc = c + d4c[l];
}
// 모래 양에 비율 계산
int rat = sand * ratio[l] / 100;
// 흩어진 모래양 합산
sum += rat;
// 범위를 벗어나면 결과값에 더하기
if (rr < 1 || rr > N || cc < 1 || cc > N) {
re += rat;
continue;
}
// 범위를 벗어나지 않으면 해당 칸에 모래를 더하기
board[rr][cc] += rat;
}
// 남은 모래를 a칸에 옮기기 위함
int rr = r, cc = c;
if (d == 1) cc = c - 1;
else if (d == 2) rr = r + 1;
else if (d == 3) cc = c + 1;
else if (d == 4) rr = r - 1;
// 범위 벗어나면 결과 값에 더하기
if (rr < 1 || rr > N || cc < 1 || cc > N) re += (sand - sum);
else board[rr][cc] += (sand - sum);
// 1,1 에 도착하면 종료
if (r == 1 && c == 1) {
cout << re;
return 0;
}
}
// 방향 전환
d++;
if (d > 4) d = 1;
}
}
}

잘 먹겠습니다 ^~^
'Algorithm > Implementation' 카테고리의 다른 글
[C++] BOJ(백준) 10800 컬러볼 (0) | 2023.02.14 |
---|---|
[C++] BOJ(백준) 17143 낚시왕 (2) | 2023.02.12 |
[C++] BOJ(백준) 20056 마법사 상어와 파이어볼 (0) | 2023.02.08 |
[C++] BOJ(백준) 16235 나무 재테크 (0) | 2023.02.06 |
[C++] BOJ(백준) 3190 뱀 (1) | 2023.02.03 |
https://www.acmicpc.net/problem/20057
20057번: 마법사 상어와 토네이도
마법사 상어가 토네이도를 배웠고, 오늘은 토네이도를 크기가 N×N인 격자로 나누어진 모래밭에서 연습하려고 한다. 위치 (r, c)는 격자의 r행 c열을 의미하고, A[r][c]는 (r, c)에 있는 모래의 양을
www.acmicpc.net
구현 문제다.
깊게 생각해야 할 부분은 없었고 문제대로 바로 구현했다.
방향이 바뀌는 점을 어떻게 처리해야 하는지 고민이었다.
4방향 좌(1) 하(2) 우(3) 상(4) 으로 나눠서 하나하나 구현했다.
방향이 변해도 흩어지는 비율은 같기 때문에 해당 배열은 한 번만 선언했다.
토네이도는 1칸 (방향전환) 1칸(방향전환) 2칸 (방향전환) 2칸 (방향전환) 3칸 ...
이런식으로 방향회전 두 번마다 이동 칸이 한 칸 씩 증가했다.
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
// 좌
int d1r[9] = { -2, -1, -1, -1, 0, 1, 1, 1, 2 };
int d1c[9] = { 0, -1, 0, 1, -2, -1, 0, 1, 0 };
// 하
int d2r[9] = { 0, 1, 0, -1, 2, 1, 0, -1, 0 };
int d2c[9] = { -2, -1, -1, -1, 0, 1, 1, 1, 2 };
// 우
int d3r[9] = { -2, -1, -1, -1, 0, 1, 1, 1, 2 };
int d3c[9] = { 0, 1, 0, -1, 2, 1, 0, -1, 0 };
// 상
int d4r[9] = { 0, -1, 0, 1, -2, -1, 0, 1, 0 };
int d4c[9] = { -2, -1, -1, -1, 0, 1, 1, 1, 2 };
// 비율
int ratio[9] = { 2, 10, 7, 1, 5, 10, 7, 1, 2 };
int board[500][500];
int main() {
// 입출력 속도를 단축시키기 위함
ios::sync_with_stdio(0);
cin.tie(0);
int N, r, c, d = 1, re = 0;
cin >> N;
for (int i = 1; i <= N; i++)
for (int j = 1; j <= N; j++) cin >> board[i][j];
// 토네이도 시작 값
r = c = N / 2 + 1;
for (int i = 1; i <= N; i++) {
for (int j = 0; j < 2; j++) {
for (int k = 0; k < i; k++) {
// 한 칸 이동
if (d == 1) c--;
else if (d == 2) r++;
else if (d == 3) c++;
else if (d == 4) r--;
int sand = board[r][c]; // 해당 칸 모래 저장
int sum = 0; // 흩어진 모래의 양 저장
board[r][c] = 0; // 토네이도가 도착한 칸은 모래가 사라짐
// 흩어지는 좌표 확인
for (int l = 0; l < 9; l++) {
int rr, cc;
if (d == 1) {
rr = r + d1r[l];
cc = c + d1c[l];
}
else if (d == 2) {
rr = r + d2r[l];
cc = c + d2c[l];
}
else if (d == 3) {
rr = r + d3r[l];
cc = c + d3c[l];
}
else if (d == 4) {
rr = r + d4r[l];
cc = c + d4c[l];
}
// 모래 양에 비율 계산
int rat = sand * ratio[l] / 100;
// 흩어진 모래양 합산
sum += rat;
// 범위를 벗어나면 결과값에 더하기
if (rr < 1 || rr > N || cc < 1 || cc > N) {
re += rat;
continue;
}
// 범위를 벗어나지 않으면 해당 칸에 모래를 더하기
board[rr][cc] += rat;
}
// 남은 모래를 a칸에 옮기기 위함
int rr = r, cc = c;
if (d == 1) cc = c - 1;
else if (d == 2) rr = r + 1;
else if (d == 3) cc = c + 1;
else if (d == 4) rr = r - 1;
// 범위 벗어나면 결과 값에 더하기
if (rr < 1 || rr > N || cc < 1 || cc > N) re += (sand - sum);
else board[rr][cc] += (sand - sum);
// 1,1 에 도착하면 종료
if (r == 1 && c == 1) {
cout << re;
return 0;
}
}
// 방향 전환
d++;
if (d > 4) d = 1;
}
}
}

잘 먹겠습니다 ^~^
'Algorithm > Implementation' 카테고리의 다른 글
[C++] BOJ(백준) 10800 컬러볼 (0) | 2023.02.14 |
---|---|
[C++] BOJ(백준) 17143 낚시왕 (2) | 2023.02.12 |
[C++] BOJ(백준) 20056 마법사 상어와 파이어볼 (0) | 2023.02.08 |
[C++] BOJ(백준) 16235 나무 재테크 (0) | 2023.02.06 |
[C++] BOJ(백준) 3190 뱀 (1) | 2023.02.03 |