AOJ1156 Twirling Robot
問題リンク Twirling Robot
- 解法
(現在位置、向き)をノードにしたダイクストラで解きます。
向きをベクトルの形にすることで複雑なif文の羅列を避けることができます。
- ソース
import java.util.Comparator; import java.util.PriorityQueue; import java.util.Scanner; //Twirling Robot public class AOJ1156 { static int[][][] dist; public static void main(String[] args) { Scanner sc = new Scanner(System.in); int[][] move = {{-1,0},{0,1},{1,0},{0,-1}}; while(true){ int w = sc.nextInt(); int h = sc.nextInt(); if((w|h)==0)break; int[][] m = new int[h][w]; for(int i=0;i<h;i++)for(int j=0;j<w;j++)m[i][j]=sc.nextInt(); int[] cost = new int[4]; for(int i=0;i<4;i++)cost[i]=sc.nextInt(); dist = new int[h][w][4]; for(int i=0;i<h;i++)for(int j=0;j<w;j++)for(int k=0;k<4;k++)dist[i][j][k]=Integer.MAX_VALUE; dist[0][0][1] = 0; PriorityQueue<int[]> q = new PriorityQueue<int[]>(h*w, new Comparator<int[]>() { public int compare(int[] o1, int[] o2) { return dist[o1[0]][o1[1]][o1[2]]-dist[o2[0]][o2[1]][o2[2]]; } }); q.add(new int[]{0,0,1}); while(!q.isEmpty()){ int[] a = q.poll(); int i = a[0]; int j = a[1]; int dir = a[2]; if(i==h-1&&j==w-1){ System.out.println(dist[i][j][dir]); break; } for(int k=0;k<4;k++){ int nd = (dir+k)%4; int ni = i+move[nd][0]; int nj = j+move[nd][1]; if(0<=ni&&ni<h&&0<=nj&&nj<w){ int c = dist[i][j][dir] + (m[i][j]==k?0:cost[k]); if(c < dist[ni][nj][nd]){ dist[ni][nj][nd] = c; q.add(new int[]{ni,nj,nd}); } } } } } } }