928:Eternal Truths

問題文
http://uva.onlinejudge.org/external/9/928.html

進む距離を1,2,3,1,2,3のように繰り返してSからEにいくときの最短ステップ数を出力せよ。行けない時はNOと出力せよ。



























幅優先探索した。

#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<cstring>
#include<cctype>
#include<queue>
#define INF 100000000
  
using namespace std;
  
int h,w,cost[4][301][301];
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
  
struct state{
    state(){}
    state(int x,int y,int moves,int cost):x(x),y(y),moves(moves),cost(cost){}
    int x,y,moves,cost;
};
  
string grid[301];
  
void bfs(state s){
      
    queue<state>que;
    que.push(s);
      
    while(!que.empty()){
        state v=que.front();
        que.pop();
        int mv=v.moves%3+1;
        if(v.cost>=cost[mv][v.y][v.x])continue;
          
        cost[mv][v.y][v.x]=v.cost;
          
        for(int i=0;i<4;i++){
            int nx=v.x+dx[i]*mv,ny=v.y+dy[i]*mv;
            if(nx<0 || ny<0 || w<=nx || h<=ny)continue;
              
            for(int j=1;j<=mv;j++)
                if(grid[v.y+dy[i]*j][v.x+dx[i]*j]=='#')goto end;
              
            que.push(state(nx,ny,v.moves+1,v.cost+1));
              
            end:;
        }
          
    }
}
  
int main(void){
    int n;
    cin >> n;
    while(n--){
        cin >> h >> w;
        for(int i=0;i<h;i++)cin >> grid[i];
          
        for(int i=0;i<4;i++){
            for(int j=0;j<301;j++){
                for(int k=0;k<301;k++){
                    cost[i][j][k]=INF;
                }
            }
        }
          
        for(int i=0;i<h;i++){
            for(int j=0;j<w;j++){
                if(grid[i][j]=='S'){
                    bfs(state(j,i,0,0));
                	goto endloop;
                }
            }
        }
        endloop:;
    	
        int ans=INF;
        for(int i=0;i<h;i++){
            for(int j=0;j<w;j++){
                if(grid[i][j]=='E'){
                    for(int k=0;k<4;k++)
                        ans=min(ans,cost[k][i][j]);
                    goto end;
                }
            }
        }
        end:;
        if(ans>=INF)cout << "NO" << endl;
        else cout << ans << endl;
    }
      
    return 0;
}