[분류]
- 구현
- 시뮬레이션
[문제링크]
[요구사항]
- 미친 아두이노와 종수가 만나면 횟수를 출력하고, 끝까지 안만나면 맵을 출력한다.
[풀이]
- 문제에 적혀있는 순서대로 그대로 구현하면 된다.
- 종수가 움직이는 것을 구현한다. 이 때, 움직일 좌표에 미친 아두이노가 있으면 종료한다.
- 이후, 미친 아두이노들을 움직인다.
- 미친 아두이노를 움직일 때, 그 자리에 종수가 있으면 바로 종료한다.
- 가장 중요한 미친 아두이노가 겹칠 때를 위해서 visited를 두어 여러 아두이노 오는 아두이노마다 1씩 더해준다.
- 이렇게 해주면 나중에 visited가 2이상 되는 칸에 오는 아두이노는 큐에 다시 넣지않고 삭제해줄 수 있다.
[코드]
//baekjoon_8972_미친아두이노
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main{
static int n, m;
static int cnt = 0;
static int MAX = 202;
static int jx=0, jy=0;
static char[][] map;
static String order;
static Queue<Node> Crazy = new LinkedList<>();
static int dx[] = {100, 1, 1, 1, 0, 0, 0, -1, -1, -1};
static int dy[] = {100, -1, 0, 1, -1, 0, 1, -1, 0, 1};
public static void main(String args[]) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
map = new char[n][m];
for(int i=0;i<n;i++){
map[i] = br.readLine().toCharArray();
for(int j=0;j<m;j++){
if(map[i][j]=='I'){
jx = i; jy = j;
}else if(map[i][j] == 'R'){
Crazy.add(new Node(i, j));
}
}
}//정보 받기
order = br.readLine();
for(int l=0;l<order.length();l++){
int idx = order.charAt(l)-'0';
//종수이동
int nx = jx + dx[idx];
int ny = jy + dy[idx];
cnt++;
if(map[nx][ny]=='R') {
System.out.println("kraj " + cnt);
return;
}
map[nx][ny]='I';
if(idx!=5){
map[jx][jy]='.';
}
jx = nx; jy = ny;
//미친 아두이노 이동
Queue<Node> Temp = new LinkedList<>();
int[][] visited = new int[n][m];
while(!Crazy.isEmpty()){
Node node = Crazy.poll();
map[node.x][node.y]='.';//이동하니까 원래 자리는 초기화
Node point = getPoint(node.x, node.y);//미친 아두이노의 방향 얻기
if(point.x==jx && point.y==jy){
System.out.println("kraj " + cnt);
return;
}//움직인 곳이 종수있는 곳이라면 종료
visited[point.x][point.y]++;
Temp.add(new Node(point.x, point.y));
}
while(!Temp.isEmpty()){
Node tmp = Temp.poll();
if(visited[tmp.x][tmp.y]==1){
map[tmp.x][tmp.y]='R';
Crazy.add(tmp);
}else{
map[tmp.x][tmp.y]='.';
}
}
}
printMap();
}
static private class Node{
int x, y;
private Node(int x, int y){
this.x = x;
this.y = y;
}
}
static private void printMap(){
for(int i=0;i<n;i++){
StringBuilder sb = new StringBuilder();
for(int j=0;j<m;j++)
sb.append(map[i][j]);
System.out.println(sb.toString());
}
}
static private Node getPoint(int cx, int cy){
int res = MAX;
int rx=cx, ry=cy;
for(int i=1;i<=9;i++){
if(i==5) continue;
int nx = cx + dx[i];
int ny = cy + dy[i];
if(isBorder(nx, ny)) continue;
int dis = Math.abs(jx-nx)+Math.abs(jy-ny);
if(res>dis){
res = dis;
rx =nx; ry=ny;
}
}
return new Node(rx, ry);
}
static private boolean isBorder(int x, int y){
return (x<0 || y<0 || x>n-1 || y>m-1);
}
}
[통과여부]
[느낀점]
정말 어이없는 곳에서 시간을 너무 많이 허비했다. 분명히 이동한 횟수를 출력하라고 해서 제자리에 있을 때는 뺐는데 포함하는 것이 답이었다. 이건 정말 문제의 조건을 더 제대로 적어줘야할 것 같다. 화난다.