문제
https://www.acmicpc.net/problem/21610
풀이
전형적인 삼성 역량 테스트의 구현 문제입니다.
우선 문제를 통해 다음의 동작으로 메서드를 구분해볼 수 있습니다.
1. 구름 이동 (moveClouds)
2. 비 내리기(rain)
3. 물 복사(copyWater)
4. 구름 만들기(makeClouds)
각 단계별 메서드를 따라 구현을 해주면 되는데, 이 문제에서 생각해 볼 것은 1번 열과 N번 열, 그리고 1번 행과 N번 행이 연결된 것을 구현하는 것입니다. 이것은 % 연산자를 통해 간단히 구현할 수 있습니다.
그리고 이 문제의 전반적인 부분에서 조심해야하는 것은, 구름을 이동하거나 물을 복사하는 동작에서, 수정된 데이터를 사용하는 것을 주의해야합니다. 그것을 방지하기 위해 ArrayList 에 담아 수정된 데이터를 사용하는 것을 막았습니다.
아래는 소스 코드입니다.
소스 코드
import java.util.ArrayList;
import java.util.Scanner;
public class B21610_마법사상어와비바라기 {
static int N,M;
static int[][] map;
static int[][] clouds;
static class Movement{
int d;
int s;
Movement(int d, int s){
this.d=d;
this.s=s;
}
}
static int[] dr = {0,-1,-1,-1,0,1,1,1};
static int[] dc = {-1,-1,0,1,1,1,0,-1};
static ArrayList<Movement> list = new ArrayList<>();
static ArrayList<int[]> waters;
static Scanner sc = new Scanner(System.in);
public static void main(String[] args) {
input();
magic();
}
static void input(){
N = sc.nextInt();
M = sc.nextInt();
map = new int[N][N];
clouds = new int[N][N];
for(int r =0;r<N;r++){
for(int c=0;c<N;c++){
map[r][c] = sc.nextInt();
}
}
for(int i = 0;i<M;i++){
int d = sc.nextInt()-1;
int s = sc.nextInt();
list.add(new Movement(d,s));
}
}
static void magic(){
for(int r = N-2;r<N;r++){
for(int c=0;c<2;c++){
clouds[r][c] = 1;
}
}
for(int i = 0; i<M;i++) {
int d = list.get(i).d;
int s = list.get(i).s;
moveClouds(d,s);
waters = new ArrayList<>();
rain();
copyWater();
makeCloud();
}
System.out.println(getSum());
}
static void moveClouds(int d, int s){
ArrayList<int[]> nows = new ArrayList<>();
for(int r =0;r<N;r++){
for(int c=0;c<N;c++){
if(clouds[r][c]==1){
nows.add(new int[]{r,c});
clouds[r][c] = 0;
}
}
}
for(int i=0;i<nows.size();i++){
int nowR = nows.get(i)[0];
int nowC = nows.get(i)[1];
int nextR = 0;
int nextC = 0;
if(nowR+dr[d]*s>=0) nextR = (nowR+dr[d]*s)%N;
else{
if(Math.abs(nowR+dr[d]*s)%N==0) nextR = 0;
else nextR = N-Math.abs(nowR+dr[d]*s)%N;
}
if(nowC+dc[d]*s>=0) nextC = (nowC+dc[d]*s)%N;
else{
if(Math.abs(nowC+dc[d]*s)%N==0) nextC = 0;
else nextC = N-Math.abs(nowC+dc[d]*s)%N;
}
clouds[nextR][nextC] = 1;
}
}
static void rain(){
for(int r =0;r<N;r++){
for(int c=0;c<N;c++){
if(clouds[r][c]==1){
map[r][c]++;
clouds[r][c] = 0;
waters.add(new int[]{r,c});
}
}
}
}
static void copyWater(){
ArrayList<int[]> copyWaters = new ArrayList<>();
for(int i=0;i<waters.size();i++){
int r = waters.get(i)[0];
int c = waters.get(i)[1];
int cnt = 0;
for(int d=1;d<8;d+=2){
int idr = r+dr[d];
int idc = c+dc[d];
if(idr<0||idc<0||idr>=N||idc>=N) continue;
if(map[idr][idc]>0) cnt++;
}
copyWaters.add(new int[]{r,c,cnt});
}
for(int i=0;i<copyWaters.size();i++){
int r = copyWaters.get(i)[0];
int c = copyWaters.get(i)[1];
int cnt =copyWaters.get(i)[2];
map[r][c] += cnt;
}
}
static void makeCloud(){
for(int r =0;r<N;r++){
outer: for(int c=0;c<N;c++){
if(map[r][c]>=2){
for(int i = 0;i<waters.size();i++){
if(r==waters.get(i)[0]&&c==waters.get(i)[1]) continue outer;
}
clouds[r][c] = 1;
map[r][c]-=2;
}
}
}
}
static int getSum(){
int sum = 0;
for(int r =0;r<N;r++){
for(int c=0;c<N;c++){
sum+=map[r][c];
}
}
return sum;
}
}
'Java > BOJ' 카테고리의 다른 글
[BOJ] 백준 18223. 민준이와 마산 그리고 건우 (0) | 2024.05.06 |
---|---|
[BOJ] 백준 15681. 트리와 쿼리 (0) | 2024.05.04 |
[BOJ] 백준 1240. 노드사이의 거리 (0) | 2024.04.26 |
[BOJ] 백준 5568. 카드놓기 (0) | 2024.04.21 |
[BOJ] 백준 1863. 스카이라인 쉬운거 (0) | 2024.04.18 |