AOJ : 1118 - Nets of Dice
問題概要
http://rose.u-aizu.ac.jp/onlinejudge/ProblemSet/description.jsp?id=1118
入力された展開図を組み立てて、立方体が作れるかどうか判定する問題。
アルゴリズム
まず、展開図の中に、1〜6の数字がそれぞれ1個ずつしかないことを確かめます。
それが成り立たない場合は、その時点で false と判定できます。
その後、展開図の中の0以外の数字のどこかからスタートして、再帰をしながらサイコロを回転させ、サイコロを完成させていきます。
最後に出来上がったサイコロが表裏足し合わせて7になるようなサイコロになっているかを確認して終了です。
詳しくはソースを見てください。
プログラム
import java.util.*; public class Main{ public static void main(String[] args){ Scanner sc = new Scanner(System.in); int n = sc.nextInt(); while(n-- > 0){ t = new int[5][5]; int m = 0; boolean[] used = new boolean[7]; boolean trueFlg = true; for(int i=0;i<5;i++){ for(int j=0;j<5;j++){ t[i][j] = sc.nextInt(); //同じ数字が出てきてないかの確認 if(t[i][j] != 0){ if(!used[t[i][j]]){ m++; used[t[i][j]] = true; } else{ trueFlg = false; } } } } if(m != 6) trueFlg = false; //サイコロ作成とサイコロが成立しているかの確認 if(trueFlg){ int sy=-1,sx=-1; for(sy=0;sy<5;sy++){ for(sx=0;sx<5;sx++) if(t[sy][sx] != 0) break; if(sx != 5) break; } Dice d = new Dice(0,0,0,0,0,0); makeDice(d,sx,sy); trueFlg = d.isDice(); } System.out.println(trueFlg ? "true" : "false"); } } private static int[][] t; private static int dx[] = {0,1,0,-1}; private static int dy[] = {-1,0,1,0}; private static void makeDice(Dice d,int x,int y){ d.b = t[y][x]; t[y][x] = 0; for(int i=0;i<4;i++){ int nx = x + dx[i]; int ny = y + dy[i]; if(nx>=0 && nx<5 && ny>=0 && ny<5 && t[ny][nx]>0){ d.move(i); makeDice(d,nx,ny); d.move((i+2)%4); } } } } class Dice{ int t,b,w,e,n,s; Dice(int t,int b,int w,int e,int n,int s){ this.t = t; this.b = b; this.w = w; this.e = e; this.n = n; this.s = s; } boolean isDice(){ return t+b==7 && w+e==7 && n+s==7; } void move(int dir){ Dice d = this.copy(); switch(dir){ case 0: t = d.s; b = d.n; n = d.t; s = d.b; break; case 1: t = d.w; b = d.e; w = d.b; e = d.t; break; case 2: t = d.n; b = d.s; n = d.b; s = d.t; break; case 3: t = d.e; b = d.w; w = d.t; e = d.b; break; } } Dice copy(){ return new Dice(t,b,w,e,n,s); } }