# BOJ 8972 - 미친 아두이노

## BOJ 8972 미친 아두이노

{% embed url="<https://www.acmicpc.net/problem/8972>" %}

종수는 입력값대로 움직이고, 아두이노는 종수와 가장 가까운 방향으로 움직인다고 합니다.

이번 문제는 시뮬레이션 문제이며, 총 5번의 과정으로 나눠서 풀어보겠습니다.

1. 입력값 받기
2. 종수와 아두이노 위치 구하기
3. 종수와 아두이노 이동시키기
4. 아두이노 파괴, 새로운 아두이노 위치 설정
5. 맵 출력하기

### 1. 입력값 받기

종수가 각 턴마다 어느 방향으로 움직이는지 저장하는 곳은 move라는 리스트에 저장합니다.

```python
n, m = map(int,input().split())
arr = [list(input()) for _ in range(n)]
move = list(map(int,list(input())))
```

move쪽에 map(int, list(input()))이 좀 생소한데요. 우리는 숫자를 하나씩 떼어서 봐야 하기 때문에 list(input())으로 \['5', '5', '5', '8', '8', '8', '8']로 한 글자씩 떼어준 후에 int형으로 전부 변환한 방법입니다.

이것은 그냥 list(input()), input()으로 값을 받아도 상관없습니다. 그런데 종수와 아두이노는 제자리걸음 포함 9개의 방향으로 이동할 예정입니다. 그래서 나중에 움직일 때,  int(move\[x])처럼 int형으로 변환해서 움직여야 합니다.

### 2. 종수와 아두이노 위치 구하기

arr 배열 안에 종수를 뜻하는 I와 아두이노를 뜻하는 R이 들어가 있습니다.

종수의 위치는 sx, sy로 설정하고, 아두이노들은 enemy라는 리스트에 넣어서 (x, y)꼴로 좌표를 저장합니다.

```python
n, m = map(int,input().split())
arr = [list(input()) for _ in range(n)]
move = list(map(int,list(input())))
enemy = []
for x in range(n):
    for y in range(m):
        if arr[x][y] == 'I': sx, sy = x, y
        if arr[x][y] == 'R': enemy.append((x,y))
```

### 3. 종수와 아두이노 이동시키기

먼저 종수가 이동하는 횟수는 move의 길이만큼 움직입니다.

```python
n, m = map(int,input().split())
arr = [list(input()) for _ in range(n)]
move = list(map(int,list(input())))
enemy = []
for x in range(n):
    for y in range(m):
        if arr[x][y] == 'I': sx, sy = x, y
        if arr[x][y] == 'R': enemy.append((x,y))
for t in range(len(move)):
    blah blah
```

이제 종수를 먼저 움직여야 하는데, 일단 dx, dy 배열을 만들어서 본문에 나온 1 \~ 9 까지 배열을 만들어줍니다.

```python
dx,dy = [1, 1, 1, 0, 0, 0, -1, -1, -1], [-1, 0, 1]*3

n, m = map(int,input().split())
arr = [list(input()) for _ in range(n)]
move = list(map(int,list(input())))
enemy = []
for x in range(n):
    for y in range(m):
        if arr[x][y] == 'I': sx, sy = x, y
        if arr[x][y] == 'R': enemy.append((x,y))
for t in range(len(move)):
    blah blah
```

이제 종수가 이동해야 하는데, 본문에서 보드를 벗어나는 입력이 주어지지 않는다고 했으므로 dx, dy는 0부터 시작하니 move\[t] -1을 넣어줘서 sx = sx + dx\[move\[t]-1], sy = sy + dy\[move\[t]-1]로 값을 수정하면 됩니다.

```python
dx,dy = [1, 1, 1, 0, 0, 0, -1, -1, -1], [-1, 0, 1]*3

n, m = map(int,input().split())
arr = [list(input()) for _ in range(n)]
move = list(map(int,list(input())))
enemy = []
for x in range(n):
    for y in range(m):
        if arr[x][y] == 'I': sx, sy = x, y
        if arr[x][y] == 'R': enemy.append((x,y))

for t in range(len(move)):
    sx, sy = sx + dx[move[t]-1], sy + dy[move[t]-1]
```

여기서 종수가 아두이노가 있는 곳으로 이동했다고 하면 게임이 지게 된다고 합니다. 종수가 이동한 후에 아두이노가 있는지 확인하기 때문에 출력문에 t+1을 넣어주면 됩니다.

```python
dx,dy = [1, 1, 1, 0, 0, 0, -1, -1, -1], [-1, 0, 1]*3

n, m = map(int,input().split())
arr = [list(input()) for _ in range(n)]
move = list(map(int,list(input())))
enemy = []
for x in range(n):
    for y in range(m):
        if arr[x][y] == 'I': sx, sy = x, y
        if arr[x][y] == 'R': enemy.append((x,y))

for t in range(len(move)):
    sx, sy = sx + dx[move[t]-1], sy + dy[move[t]-1]
    if (sx, sy) in enemy:
        print("kraj {}".format(t+1))
        exit(0)
```

이제 아두이노를 이동해야 합니다. 먼저 아두이노를 이동하기 전에 문제 본문에서 아두이노가 겹쳐있으면 겹쳐있는 아두이노들은 전부 파괴된다고 하니까 (x, y)에서 아두이노가 몇 개가 있는지 확인하는 배열을 하나 만듭니다.

```python
dx,dy = [1, 1, 1, 0, 0, 0, -1, -1, -1], [-1, 0, 1]*3

n, m = map(int,input().split())
arr = [list(input()) for _ in range(n)]
move = list(map(int,list(input())))
enemy = []
for x in range(n):
    for y in range(m):
        if arr[x][y] == 'I': sx, sy = x, y
        if arr[x][y] == 'R': enemy.append((x,y))

for t in range(len(move)):
    sx, sy = sx + dx[move[t]-1], sy + dy[move[t]-1]
    if (sx, sy) in enemy:
        print("kraj {}".format(t+1))
        exit(0)
    
    amount = [[0]*m for _ in range(n)]
```

그리고 enemy에서 원소를 하나씩 꺼내어 종수와 가까운 거리로 이동하면 됩니다. 이때 원소를 하나씩 꺼내는 방법은 while(enemy)와 pop을 이용합니다.

```python
dx, dy = [1, 1, 1, 0, 0, 0, -1, -1, -1], [-1, 0, 1] * 3

n, m = map(int, input().split())
arr = [list(input()) for _ in range(n)]
move = list(map(int, list(input())))
enemy = []
for x in range(n):
    for y in range(m):
        if arr[x][y] == 'I': sx, sy = x, y
        if arr[x][y] == 'R': enemy.append((x, y))

for t in range(len(move)):
    sx, sy = sx + dx[move[t]-1], sy + dy[move[t]-1]
    if (sx, sy) in enemy:
        print("kraj {}".format(t + 1))
        exit(0)

    amount = [[0] * m for _ in range(n)]
    while(enemy):
        x, y = enemy.pop()
```

이제 x와 y를 9개의 방향으로 움직이면서 가장 종수와 가까운 위치를 찾으면 됩니다. 사실 아두이노가 움직일 방향은 제자리걸음을 제외한 8개의 방향이지만, dx, dy에 인덱스 접근을 쉽게 하기 위해서 9개의 방향이라 합시다.

그리고 9개의 방향을 다 확인해보고, 아두이노를 종수와 가까운 곳으로 이동해야 하기 때문에 ex, ey라는 변수에 이동할 위치를 설정해둡시다.

```python
dx, dy = [1, 1, 1, 0, 0, 0, -1, -1, -1], [-1, 0, 1] * 3

n, m = map(int, input().split())
arr = [list(input()) for _ in range(n)]
move = list(map(int, list(input())))
enemy = []
for x in range(n):
    for y in range(m):
        if arr[x][y] == 'I': sx, sy = x, y
        if arr[x][y] == 'R': enemy.append((x, y))

for t in range(len(move)):
    sx, sy = sx + dx[move[t]-1], sy + dy[move[t]-1]
    if (sx, sy) in enemy:
        print("kraj {}".format(t + 1))
        exit(0)

    amount = [[0] * m for _ in range(n)]
    while(enemy):
        x, y = enemy.pop()
        ex, ey = x, y
        for i in range(9):
            nx, ny = x + dx[i], y + dy[i]
```

이제 nx와 ny가 보드 범위 내에 있는지 확인해보고, 보드 내에 있으면 (ex, ey)와 (sx, sy)중 어느 좌표가 더 종수와 가까운지 확인해서 ex, ey를 업데이트해주면 됩니다.

```python
dx, dy = [1, 1, 1, 0, 0, 0, -1, -1, -1], [-1, 0, 1] * 3

n, m = map(int, input().split())
arr = [list(input()) for _ in range(n)]
move = list(map(int, list(input())))
enemy = []
for x in range(n):
    for y in range(m):
        if arr[x][y] == 'I': sx, sy = x, y
        if arr[x][y] == 'R': enemy.append((x, y))

for t in range(len(move)):
    sx, sy = sx + dx[move[t]-1], sy + dy[move[t]-1]
    if (sx, sy) in enemy:
        print("kraj {}".format(t + 1))
        exit(0)

    amount = [[0] * m for _ in range(n)]
    while(enemy):
        x, y = enemy.pop()
        ex, ey = x, y
        for i in range(9):
            nx, ny = x + dx[i], y + dy[i]
            if 0 <= nx < n and 0 <= ny < m:
                if abs(sx-ex) + abs(sy-ey) > abs(sx-nx) + abs(sy-ny):
                    ex, ey = nx, ny
```

그리고 이제 우리는 amount\[ex]\[ey]에 1을 더해주면 됩니다. 그리고 아두이노가 종수가 있는 곳으로 이동하게 되면 게임이 끝난다고 합니다.

```python
dx, dy = [1, 1, 1, 0, 0, 0, -1, -1, -1], [-1, 0, 1] * 3

n, m = map(int, input().split())
arr = [list(input()) for _ in range(n)]
move = list(map(int, list(input())))
enemy = []
for x in range(n):
    for y in range(m):
        if arr[x][y] == 'I': sx, sy = x, y
        if arr[x][y] == 'R': enemy.append((x, y))

for t in range(len(move)):
    sx, sy = sx + dx[move[t]-1], sy + dy[move[t]-1]
    if (sx, sy) in enemy:
        print("kraj {}".format(t + 1))
        exit(0)

    amount = [[0] * m for _ in range(n)]
    while(enemy):
        x, y = enemy.pop()
        ex, ey = x, y
        for i in range(9):
            nx, ny = x + dx[i], y + dy[i]
            if 0 <= nx < n and 0 <= ny < m:
                if abs(sx-ex) + abs(sy-ey) > abs(sx-nx) + abs(sy-ny):
                    ex, ey = nx, ny
        amount[ex][ey] += 1
        if sx == ex and sy == ey:
            print("kraj {}".format(t+1))
            exit(0)
```

### 4. 아두이노 파괴, 새로운 아두이노 위치 설정

아두이노 파괴와 새로운 아두이노 위치 설정은 amount 배열을 이용해서 만들 수 있습니다. 우리는 amount 배열에 (x, y)에 있는 아두이노의 개수를 넣어뒀으니 amount\[x]\[y] = 1이면 아두이노가 있을 것이고, amount\[x]\[y] = 0 or 2 이상인 경우엔 아두이노가 원래 없거나, 있었는데 파괴된 경우입니다. 그래서 amount\[x]\[y] = 1일 때만 enemy에 다시 넣어주면 됩니다.

```python
dx, dy = [1, 1, 1, 0, 0, 0, -1, -1, -1], [-1, 0, 1] * 3

n, m = map(int, input().split())
arr = [list(input()) for _ in range(n)]
move = list(map(int, list(input())))
enemy = []
for x in range(n):
    for y in range(m):
        if arr[x][y] == 'I': sx, sy = x, y
        if arr[x][y] == 'R': enemy.append((x, y))

for t in range(len(move)):
    sx, sy = sx + dx[move[t]-1], sy + dy[move[t]-1]
    if (sx, sy) in enemy:
        print("kraj {}".format(t + 1))
        exit(0)

    amount = [[0] * m for _ in range(n)]
    while(enemy):
        x, y = enemy.pop()
        ex, ey = x, y
        for i in range(9):
            nx, ny = x + dx[i], y + dy[i]
            if 0 <= nx < n and 0 <= ny < m:
                if abs(sx-ex) + abs(sy-ey) > abs(sx-nx) + abs(sy-ny):
                    ex, ey = nx, ny
        amount[ex][ey] += 1
        if sx == ex and sy == ey:
            print("kraj {}".format(t+1))
            exit(0)
        
    for x in range(n):
        for y in range(m):
            if amount[x][y] == 1: enemy.append((x,y))
```

### 5. 새로운 맵 만들기

for문이 끝나면 종수가 아두이노를 피했기 때문에 보드의 상태를 출력하라고 합니다.

우리는 '.'으로 채워져 있는 배열을 만들고, enemy에 있는 아두이노 좌표와 종수의 위치인 sx, sy를 이용해서 보드에 값을 채워주면 됩니다.

```python
dx, dy = [1, 1, 1, 0, 0, 0, -1, -1, -1], [-1, 0, 1] * 3

n, m = map(int, input().split())
arr = [list(input()) for _ in range(n)]
move = list(map(int, list(input())))
enemy = []
for x in range(n):
    for y in range(m):
        if arr[x][y] == 'I': sx, sy = x, y
        if arr[x][y] == 'R': enemy.append((x, y))

for t in range(len(move)):
    sx, sy = sx + dx[move[t]-1], sy + dy[move[t]-1]
    if (sx, sy) in enemy:
        print("kraj {}".format(t + 1))
        exit(0)

    amount = [[0] * m for _ in range(n)]
    while(enemy):
        x, y = enemy.pop()
        ex, ey = x, y
        for i in range(9):
            nx, ny = x + dx[i], y + dy[i]
            if 0 <= nx < n and 0 <= ny < m:
                if abs(sx-ex) + abs(sy-ey) > abs(sx-nx) + abs(sy-ny):
                    ex, ey = nx, ny
        amount[ex][ey] += 1
        if sx == ex and sy == ey:
            print("kraj {}".format(t+1))
            exit(0)

    for x in range(n):
        for y in range(m):
            if amount[x][y] == 1: enemy.append((x,y))

arr = [['.']*m for _ in range(n)]
arr[sx][sy] = 'S'
for x, y in enemy:
    arr[x][y] = 'R'
```

그리고 이제 출력을 해주면 됩니다.

```python
dx, dy = [1, 1, 1, 0, 0, 0, -1, -1, -1], [-1, 0, 1] * 3

n, m = map(int, input().split())
arr = [list(input()) for _ in range(n)]
move = list(map(int, list(input())))
enemy = []
for x in range(n):
    for y in range(m):
        if arr[x][y] == 'I': sx, sy = x, y
        if arr[x][y] == 'R': enemy.append((x, y))

for t in range(len(move)):
    sx, sy = sx + dx[move[t]-1], sy + dy[move[t]-1]
    if (sx, sy) in enemy:
        print("kraj {}".format(t + 1))
        exit(0)

    amount = [[0] * m for _ in range(n)]
    while(enemy):
        x, y = enemy.pop()
        ex, ey = x, y
        for i in range(9):
            nx, ny = x + dx[i], y + dy[i]
            if 0 <= nx < n and 0 <= ny < m:
                if abs(sx-ex) + abs(sy-ey) > abs(sx-nx) + abs(sy-ny):
                    ex, ey = nx, ny
        amount[ex][ey] += 1
        if sx == ex and sy == ey:
            print("kraj {}".format(t+1))
            exit(0)

    for x in range(n):
        for y in range(m):
            if amount[x][y] == 1: enemy.append((x,y))

arr = [['.']*m for _ in range(n)]
arr[sx][sy] = 'I'
for x, y in enemy:
    arr[x][y] = 'R'

for i in range(n):
    print(''.join(arr[i]))
```
