Problem:
A Light Road

There is an evil creature in a square on N-by-M grid (2 \leq N, M \leq 100),
and you want to kill it using a laser generator located in a different square.
Since the location and direction of the laser generator are fixed,
you may need to use several mirrors to reflect laser beams.
There are some obstacles on the grid and you have a limited number of mirrors.
Please find out whether it is possible to kill the creature,
and if possible, find the minimum number of mirrors.

There are two types of single-sided mirrors;
type P mirrors can be placed at the angle of 45 or 225 degrees from east-west direction,
and type Q mirrors can be placed with at the angle of 135 or 315 degrees.
For example, four mirrors are located properly, laser go through like the following.

Note that mirrors are single-sided,
and thus back side (the side with cross in the above picture) is not reflective.
You have A type P mirrors, and also A type Q mirrors (0 \leq A \leq 10).
Although you cannot put mirrors onto the squares with the creature or the laser generator,
laser beam can pass through the square.
Evil creature is killed if the laser reaches the square it is in.

Input

Each test case consists of several lines.

The first line contains three integers, N, M, and A.
Each of the following N lines contains M characters,
and represents the grid information.
'#', '.', 'S', 'G' indicates obstacle, empty square,
the location of the laser generator, and the location of the evil creature, respectively.
The first line shows the information in northernmost squares
and the last line shows the information in southernmost squares.
You can assume that there is exactly one laser generator and exactly one creature,
and the laser generator emits laser beam always toward the south.

Output

Output the minimum number of mirrors used if you can kill creature, or -1 otherwise.

Sample Input 1

3 3 2
S#.
...
.#G

Output for the Sample Input 1

2

Sample Input 2

3 3 1
S#.
...
.#G

Output for the Sample Input 2

-1

Sample Input 3

3 3 1
S#G
...
.#.

Output for the Sample Input 3

2

Sample Input 4

4 3 2
S..
...
..#
.#G

Output for the Sample Input 4

-1

Solution in Scala (judge verdict: Accepted)

import java.util
import java.util.ArrayDeque

object Main extends App {
  import scala.io.StdIn._
  val Array(n, m, a) = readLine.trim.split(' ').map(_.toInt)
  val state = Array.tabulate(n){_ => readLine.trim}
  val emitter = (0 until n).collectFirst(y => (0 until m).find(x => state(y)(x) == 'S') match {case Some(x) => Coordinate(x, y)}).head
  val goal = (0 until n).collectFirst(y => (0 until m).find(x => state(y)(x) == 'G') match {case Some(x) => Coordinate(x, y)}).head
  val queue = new util.ArrayDeque[State]()
  val reached = Array.fill(n){Array.fill(m){Array.fill(a + 1){Array.fill(a + 1){false}}}}
  queue.add(State(emitter, a))
  reached(emitter.y)(emitter.x)(a)(a) = true
  while (!queue.isEmpty && queue.getFirst.position != goal) {
    val current = queue.removeFirst()
    //println(current)
    for (forward <- current.succ if (0 until m).contains(forward.position.x) && (0 until n).contains(forward.position.y) && state(forward.position.y)(forward.position.x) != '#') {
      if (!reached(forward.position.y)(forward.position.x)(forward.typeP)(forward.typeQ)) {
        queue.addFirst(forward)
        reached(forward.position.y)(forward.position.x)(forward.typeP)(forward.typeQ) = true
      }
      //println(s"forward: $forward, state: ${state(forward.head.y)(forward.head.x)}")
    }
    for (reflected <- current.reflect if (0 until m).contains(reflected.position.x) && (0 until n).contains(reflected.position.y) && state(reflected.position.y)(reflected.position.x) != '#') {
      if (!reached(reflected.position.y)(reflected.position.x)(reflected.typeP)(reflected.typeQ)) {
        queue.addLast(reflected)
        reached(reflected.position.y)(reflected.position.x)(reflected.typeP)(reflected.typeQ) = true
      }
      //println(s"reflected: $reflected")
    }
  }
  //println(if (!queue.isEmpty) queue.getFirst else None)
  println(if (queue.isEmpty) -1 else 2 * a - queue.getFirst.restMirror)

  case class State(typeP: Int, typeQ: Int, position: Coordinate, dir: Dir) {
    def restMirror = typeP + typeQ
    def succ: Option[State] = if (emitter == position && dir == Up) None else Some(copy(position = position.move(dir)))
    def reflect: List[State] = List(useP, useQ).flatten
    def useP: Option[State] = typeP match {
      case 0 => None
      case rest if position != emitter => Some(copy(typeP = rest - 1, dir = dir.reflect(TypeP)))
      case _ => None
    }
    def useQ: Option[State] = typeQ match {
      case 0 => None
      case rest if position != emitter => Some(copy(typeQ = rest - 1, dir = dir.reflect(TypeQ)))
      case _ => None
    }
  }
  object State {
    def apply(emitter: Coordinate, a: Int): State = State(a, a, emitter, Down)
  }
  case class Coordinate(x: Int, y: Int) {
    def move(dir: Dir): Coordinate = dir match {
      case Up => copy(y = y - 1)
      case Right => copy(x = x + 1)
      case Down => copy(y = y + 1)
      case Left => copy(x = x - 1)
    }
    def -(that: Coordinate): Coordinate = Coordinate(x - that.x, y - that.y)
    def direction(to: Coordinate): Option[Dir] = (to - this) match {
      case Coordinate(0, dy) if dy > 0 => Some(Down)
      case Coordinate(0, dy) if dy < 0 => Some(Up)
      case Coordinate(dx, 0) if dx > 0 => Some(Right)
      case Coordinate(dx, 0) if dx < 0 => Some(Left)
      case _ => None
    }
  }
  case class Laser(from: Coordinate, to: Coordinate) {
    def hasIntersection(position: Coordinate): Boolean = from == position || to == position || ((from.direction(position), to.direction(position)) match {
      case (Some(a), Some(b)) if a == b.reverse => true
      case _ => false
    })
    def succ: Laser = Laser(from, to.move(from.direction(to).get))
    def reflected(mirror: Mirror): Laser = Laser(to, to.move(from.direction(to).get.reflect(mirror)))
  }
  object Laser {
    def fromEmitter(emitter: Coordinate): Laser = Laser(emitter, emitter.move(Down))
  }
  sealed trait Dir {
    def toInt: Int = this match {
      case Up => 0
      case Right => 1
      case Down => 2
      case Left => 3
    }
    def reverse: Dir = Dir.fromInt(toInt + 2)
    def reflect(mirror: Mirror): Dir = mirror.reflect(this)
  }
  object Dir {
    def fromInt(value: Int): Dir = value & 3 match {
      case 0 => Up
      case 1 => Right
      case 2 => Down
      case 3 => Left
    }
  }
  case object Up extends Dir
  case object Right extends Dir
  case object Down extends Dir
  case object Left extends Dir
  sealed trait Mirror {
    def reflect(dir: Dir): Dir
  }
  case object TypeP extends Mirror {
    override def reflect(dir: Dir): Dir = dir match {
      case Up => Left
      case Right => Down
      case Down => Right
      case Left => Up
    }
  }
  case object TypeQ extends Mirror {
    override def reflect(dir: Dir): Dir = dir match {
      case Up => Right
      case Right => Up
      case Down => Left
      case Left => Down
    }
  }
}