본문 바로가기
Study/Algorithm

[Algorithm]BOJ_20056_마법사 상어와 파이어볼_Go

by _royJang 2021. 8. 23.
반응형

문제 링크

BOJ 20056 마법사 상어와 파이어볼

풀이 방법

어느정도 구현 문제에 대한 풀이방법을 깨우쳐 가는듯 하다. 다름이 아니라 해야할 것의 순서를 잘 지키는것..

\1. 맵의 필드에 하나 이상의 파이어 볼이 있을 경우 파이어 볼을 섞는다.(X) 이렇게 생각하는 순간 시간은 총알 같이 사라질것이다..

  1. 모든 파이어 볼을 이동한다.
  2. 이동한 파이어 볼은 따로 모아둔다.
  3. 모든 이동한 파이어볼을 삭제한다.
  4. 모든 필드에 따로 모아둔 파이어볼이 있을 경우
  • 파이어볼이 한 개 일 경우
  • 파이어볼이 두 개 이상일 경우
    조건에 맞게 조합한 후 따로 모아둔 필드에서 이동 할 파이어 볼 필드로 옮긴다.
  1. 따로 모아둔 파이어 볼을 삭제한다.
package q20056

import (
    "bufio"
    "fmt"
    "os"
    "strconv"
)

type field struct {
    fireBall []*fireBall
    stack    []*fireBall
}

type fireBall struct {
    mass  int
    speed int
    dir   int
}

var N, M, K int
var dr = []int{-1, -1, 0, 1, 1, 1, 0, -1}
var dc = []int{0, 1, 1, 1, 0, -1, -1, -1}
var mmap [][]field

func goFireBall() {
    for row := 1; row <= N; row++ {
        for col := 1; col <= N; col++ {
            if len(mmap[row][col].fireBall) == 0 {

            } else if len(mmap[row][col].fireBall) == 1 {
                nextRow := row + dr[mmap[row][col].fireBall[0].dir]*(mmap[row][col].fireBall[0].speed%N)
                nextCol := col + dc[mmap[row][col].fireBall[0].dir]*(mmap[row][col].fireBall[0].speed%N)
                nextRow, nextCol = checkRange(nextRow, nextCol)
                mmap[nextRow][nextCol].stack = append(mmap[nextRow][nextCol].stack, mmap[row][col].fireBall[0])
            } else {
                for i := 0; i < len(mmap[row][col].fireBall); i++ {
                    nextRow := row + dr[mmap[row][col].fireBall[i].dir]*(mmap[row][col].fireBall[i].speed%N)
                    nextCol := col + dc[mmap[row][col].fireBall[i].dir]*(mmap[row][col].fireBall[i].speed%N)
                    nextRow, nextCol = checkRange(nextRow, nextCol)
                    mmap[nextRow][nextCol].stack = append(mmap[nextRow][nextCol].stack, mmap[row][col].fireBall[i])
                }
            }
            mmap[row][col].fireBall = nil
        }
    }
}
func mix() {
    for row := 1; row <= N; row++ {
        for col := 1; col <= N; col++ {
            if len(mmap[row][col].stack) == 0 {

            } else if len(mmap[row][col].stack) == 1 {
                mmap[row][col].fireBall = append(mmap[row][col].fireBall, mmap[row][col].stack[0])
            } else {
                madeBalls := makeFireBalls(mmap[row][col].stack)
                if madeBalls != nil {
                    mmap[row][col].fireBall = append(mmap[row][col].fireBall, madeBalls...)
                }
            }
            mmap[row][col].stack = nil
        }
    }
}

func makeFireBalls(fireBalls []*fireBall) []*fireBall {
    var madeFireBalls [4]*fireBall
    var amountMass int
    var amountSpeed int
    isSameDir := fireBalls[0].dir % 2
    isSame := true
    fireBallsLen := len(fireBalls)
    for i := 0; i < fireBallsLen; i++ {
        amountMass += fireBalls[i].mass
        amountSpeed += fireBalls[i].speed
        if isSameDir != fireBalls[i].dir%2 {
            isSame = false
        }
    }
    dir := [4]int{0, 2, 4, 6}
    mass := amountMass / 5
    speed := amountSpeed / fireBallsLen
    if !isSame {
        for i := 0; i < 4; i++ {
            dir[i]++
        }
    }
    if mass == 0 {
        return nil
    }
    for i := 0; i < 4; i++ {
        madeFireBalls[i] = &fireBall{mass, speed, dir[i]}
    }
    return madeFireBalls[:]
}

func checkRange(row, col int) (int, int) {
    if row > N {
        row = row - N
    }
    if row <= 0 {
        row = row + N
    }
    if col > N {
        col = col - N
    }
    if col <= 0 {
        col = col + N
    }
    return row, col
}

func strToInt(str string) int {
    val, _ := strconv.Atoi(str)
    return val
}

func Start() {
    fmt.Scan(&N, &M, &K)
    scanner := bufio.NewScanner(os.Stdin)
    scanner.Split(bufio.ScanWords)
    mmap = make([][]field, N+1)
    for i := 1; i <= N; i++ {
        mmap[i] = make([]field, N+1)
    }
    for i := 0; i < M; i++ {
        var input [5]int
        for j := 0; j < 5; j++ {
            scanner.Scan()
            input[j] = strToInt(scanner.Text())
        }
        r, c, m, s, d := input[0], input[1], input[2], input[3], input[4]
        mmap[r][c].fireBall = append(mmap[r][c].fireBall, &fireBall{m, s, d})
    }
    for i := 0; i < K; i++ {
        goFireBall()
        mix()
    }
    var answer int
    for i := 1; i <= N; i++ {
        for j := 1; j <= N; j++ {
            for k := 0; k < len(mmap[i][j].fireBall); k++ {
                answer += mmap[i][j].fireBall[k].mass
            }
        }
    }
    fmt.Println(answer)
}

맞다 1번 실수는 내가한 짓이다.
어떻게 풀지 정확히 생각하고 풀어나가자

반응형