Life Engineering
[BOJ 20057] 마법사 상어와 토네이도 (Java) 본문
https://www.acmicpc.net/problem/20057
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main_BOJ_20057 {
static double[][] left= {{0,0,0.02,0,0},{0,0.1,0.07,0.01,0},{0.05,0,0,0,0}, {0,0.1,0.07,0.01,0},{0,0,0.02,0,0}};
static double[][] right=new double[5][5];
static double[][] up=new double[5][5];
static double[][] down=new double[5][5];
static int[][] center= {{2,3},{1,2},{2,1},{3,2}};
static int[][] map;
static int[] dr= {0,1,0,-1}; //좌 하 우 상
static int[] dc= {-1,0,1,0};
static int len=2;
static int count=0;
static int N;
static int r, c, dir;
static int answer=0;
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st=null;
N=Integer.parseInt(br.readLine());
map=new int[N][N];
for (int i = 0; i <N; i++) {
st=new StringTokenizer(br.readLine());
for (int j = 0; j < N; j++) {
map[i][j]=Integer.parseInt(st.nextToken());
}
}
r=N/2;
c=N/2;
dir=0;
for (int i=0; i<5; i++) {
for (int j=0; j<5; j++) {
up[i][j]=left[4-j][i];
down[i][j]=left[j][4-i];
right[i][j]=left[4-i][4-j];
}
}
for (int i=2; i<=N; i++) {
move(r, c, i, dir); //r,c 갱신
move(r, c, i, dir);
if (i==N) {
move(r, c, i, dir);
}
}
System.out.println(answer);
}
private static void move(int r2, int c2, int cnt, int dir2) {
double[][] temp=directions(dir2);
for (int i=0; i<cnt-1; i++) { //한번 흩날리기 (시작점: r2, c2)
int move_r=center[dir2][0]-r2;
int move_c=center[dir2][1]-c2;
int y_r=r2+dr[dir2];
int y_c=c2+dc[dir2];
int sum=map[y_r][y_c];
for (int j=0; j<5; j++) { //a일때 경계 벗어날 때 체크
for (int k=0; k<5; k++) {
if (temp[j][k]>0) {
int sand=(int)(map[y_r][y_c]*temp[j][k]);
if (isOutside(j-move_r, k-move_c)) {
answer+=sand;
sum-=sand;
}
else {
map[j-move_r][k-move_c]+=sand;
sum-=sand;
}
}
}
}
int a_r=y_r+dr[dir2];
int a_c=y_c+dc[dir2];
if (isOutside(a_r, a_c)) {
answer+=sum;
}
else {
map[a_r][a_c]+=sum;
}
map[y_r][y_c]=0;
r2=y_r;
c2=y_c;
}
r=r2;
c=c2;
dir=(dir2+1)%4;
}
private static boolean isOutside(int r, int c) {
return r<0 || c<0 || r>=N || c>=N;
}
private static double[][] directions(int i) {
if (i==0) return left;
else if (i==1) return down;
else if (i==2) return right;
else return up;
}
}
시뮬레이션 문제.. 은근 까다로웠다.
흩날리는 비율을 표시한 표를 각각 오른쪽으로 이동, 위쪽으로 이동, 아래쪽으로 이동할 경우를 고려해서 회전시켜준다.
평행이동처럼 구현했다. 이동 방향에 따라 흩날리는 비율을 표시한 표를 map과 매칭시켜, 경계를 넘어설 경우 answer 값에 저장하고 그 외의 경우에는 문제의 조건대로 그대로 구현했다..
평행이동+회전을 이용해서 풀었다.
'Problem Solving' 카테고리의 다른 글
[BOJ 1175] 배달 (Java) (0) | 2022.04.04 |
---|---|
[BOJ 14442] 벽 부수고 이동하기 2 (Java) (0) | 2022.04.03 |
[BOJ 1194] 달이 차오른다, 가자. (Java) (0) | 2022.04.01 |
[BOJ 4485] 녹색 옷 입은 애가 젤다지? (Java) (0) | 2022.04.01 |
[BOJ 1062] 가르침 (Java) (0) | 2022.03.31 |