AOJ0569 Illumination
問題リンク Illumination
- 解法
建物があるマスにおいて、隣接している屋外のマスの数だけ飾りが必要になります。よって、屋外であるかどうかの判定表を先に作ります。適当な屋外のマス( (0,0)など )から幅優先探索をかければ作れます。あとは、建物マスについて、上述したとおりに隣接屋外マスを数えるだけです。
y座標の偶奇で移動するマスの座標が変わるので注意です。
- ソース
import java.util.ArrayList; import java.util.List; import java.util.Scanner; //Illumination public class AOJ0569 { int[][] d0 = {{-1,0},{-1,1},{0,-1},{0,1},{1,0},{1,1}}, d1 = {{-1,-1},{-1,0},{0,-1},{0,1},{1,-1},{1,0}}; void run(){ Scanner sc = new Scanner(System.in); int w = sc.nextInt(), h = sc.nextInt(); boolean[][] u = new boolean[h+2][w+2], v = new boolean[h+2][w+2]; for(int i=1;i<=h;i++)for(int j=1;j<=w;j++)u[i][j]=sc.nextInt()==1; v[0][0] = true; List<int[]> l = new ArrayList<int[]>(); l.add(new int[]{0, 0}); while(!l.isEmpty()){ List<int[]> next = new ArrayList<int[]>(); for(int[]a:l){ int pi = a[0], pj = a[1]; for(int k=0;k<6;k++){ int ni = pi + (pi%2==1?d0[k][0]:d1[k][0]), nj = pj + (pi%2==1?d0[k][1]:d1[k][1]); if(0<=ni&&ni<=h+1&&0<=nj&&nj<=w+1&&!u[ni][nj]&&!v[ni][nj]){ v[ni][nj] = true; next.add(new int[]{ni, nj}); } } } l = next; } int res = 0; for(int i=1;i<=h;i++)for(int j=1;j<=w;j++)if(u[i][j]){ for(int k=0;k<6;k++){ int ni = i + (i%2==1?d0[k][0]:d1[k][0]), nj = j + (i%2==1?d0[k][1]:d1[k][1]); if(v[ni][nj])res++; } } System.out.println(res); } public static void main(String[] args) { new AOJ0569().run(); } }