No.351 市松スライドパズル
逆シミュレーションする。
求めたいのは「最終的に左上のマスが何色であったか」なので、「最終盤面の左上のマスは、最初の盤面のどの位置から運ばれてきたか」を考える。
最終盤面の左上のマスの座標をx=0,y=0とおく。操作を後ろから順に行っていって、Rの番号が現在のxと一致していたらxから1引く。xがもし負の値になったら(盤面の左端からはみ出てしまったら)、Wを足す(盤面の右端におく)。同様に、Cの番号が現在のyと一致していたらyから1引く。負の値ならHを足す。
Rの番号がxと一致しない、あるいはCの番号がyと一致しない場合は何もしない。
全ての操作を処理し終えたときの(x,y)が「最初の盤面における、最終盤面の左上のマスの位置」である。このマスが、n回の操作のすえに最終的に左上まで運ばれてくるということになる。つまり、最初の盤面におけるマス(x,y)が何色かを考えればよい。これは、x+yが偶数なら白、x+yが奇数なら黒になる。
import java.util.*; import static java.lang.System.*; public class Blog { static Scanner sc = new Scanner(System.in); public static void main(String[] args) { int H = sc.nextInt(); int W = sc.nextInt(); int n = sc.nextInt(); Operation[] op = new Operation[n]; for (int i=0; i<n; i++) {op[i] = new Operation(sc.next().charAt(0),sc.nextInt());} int x = 0, y = 0; for (int i=n-1; i>=0; i--) { if (op[i].RC=='R' && op[i].num==y) { x--; x += x<0?W:0; } else if (op[i].RC=='C' && op[i].num==x) { y--; y += y<0?H:0; } } out.println((x+y)%2==0?"white":"black"); } } class Operation { char RC; int num; Operation (char c, int n) { this.RC = c; this.num = n; } }