AOJ1214 Walking Ant
問題リンク Walking Ant
- 概要
大きさH*Wのマップがあり、蟻と蟻の家と食べ物と石がある。蟻は単位時間に上下左右4マスに動くことができる。石のある場所は通れない。蟻が自分の家にたどり着くのにかかる最短時間を答えよ。
蟻はHPを持っており、その初期値と最大値は6である。蟻は単位時間毎に1HPずつ失い、0になると死んでしまう。
蟻は食べ物にたどり着くとそれを食べてHPを最大値まで回復できる。食べ物は大きいのでいくら食べても無くならない。
ただし、蟻は移動した結果HPが0になった瞬間に死んでしまうので、たとえそのマスが家でも到着したことにならず、食べ物でも回復することができない。家にたどり着くことができない場合は-1と答えよ。
W, H <= 8
- 解法
(座標, 残りHP)を頂点としたダイクストラもとい幅優先探索で解けます。
- ソース
import java.util.ArrayList; import java.util.List; import java.util.Scanner; //Walking Ant public class AOJ1214 { void run(){ int[][] move = {{-1,0},{0,1},{1,0},{0,-1}}; Scanner sc = new Scanner(System.in); for(;;){ int w = sc.nextInt(), h = sc.nextInt(); if((w|h)==0)break; int[][] map = new int[h][w]; int si = -1, sj = -1; for(int i=0;i<h;i++)for(int j=0;j<w;j++){ map[i][j] = sc.nextInt(); if(map[i][j]==2){ si = i; sj = j; map[i][j] = 1; } } boolean[][][] u = new boolean[h][w][7]; u[si][sj][6] = true; List<int[]> l = new ArrayList<int[]>(); l.add(new int[]{si, sj, 6}); int step = 0; int ans = -1; while(!l.isEmpty()){ List<int[]> next = new ArrayList<int[]>(); for(int[]a:l){ int i = a[0], j = a[1], hp = a[2]; if(map[i][j]==3){ ans = step; next.clear(); break; } if(hp<=1)continue; for(int k=0;k<4;k++){ int ni = i+move[k][0]; int nj = j+move[k][1]; if(0<=ni&&ni<h&&0<=nj&&nj<w&&map[ni][nj]!=0){ if(map[ni][nj]==4){ if(u[ni][nj][6])continue; u[ni][nj][6] = true; next.add(new int[]{ni, nj, 6}); } else{ if(u[ni][nj][hp-1])continue; u[ni][nj][hp-1] = true; next.add(new int[]{ni, nj, hp-1}); } } } } step++; l = next; } System.out.println(ans); } } public static void main(String[] args) { new AOJ1214().run(); } }