【PGBATTLE2020_せんべい3】左手法(Left-Hand Rule)​

過去問:https://products.sint.co.jp/q_list_2020
解答コード:https://products.sint.co.jp/hubfs/resource/topsic/pgb2020/code.pdf

アルゴロジックで左手探索の実装を知っていたので再現。https://www.youtube.com/watch?v=ZrsBq4TEji4

1. 進んだら左に回転。
2. 壁なら右に回転。
をするだけでよさそうです。

Q.  if (DP[y][x]>4) break?
A. ループ判定。
十字路のループ判定は、同じ場所を5回通ったらもれなくループしてるといえそう。

実装。

ll H, W;
ll sy, sx, gy, gx;
char C[1010][1010];
ll DP[1010][1010];

void leftd(ll &d){
 d=(d+3)%4;
 return ;
}
void rightd(ll &d){
 d=(d+1)%4;
 return ;
}

void debug(){
 rep(i, H){
   rep(j, W){
     cout << DP[i][j];
   }
   cout << endl;
 }
}

int main(){
 cincout();
 
 cin >> H >> W >> sy >> sx >> gy >> gx;
 --sy, --sx, --gy, --gx;
 rep(i, H) rep(j, W) cin >> C[i][j];
 ll y=sy;
 ll x=sx;
 ll d=0;
 ++DP[y][x];
 ll turn = 0;
 bool fin=false;
 while(1){
   if (y == gy && x == gx){
     fin=true;
     break;
   }
   if (DP[y][x]>4) break;
   
   leftd(d);
   bool cant=false;
   rep(n, 5){
     if (n==4){
       cant=true;
       break;
     }
     ll ny = y+dy[d];
     ll nx = x+dx[d];
     if (ny<0 || nx<0 || ny>=H || nx>=W){
       rightd(d);
       continue;
     }
     if (C[ny][nx] == '.') break;
     rightd(d);
   }
   if (cant) break;
   y += dy[d];
   x += dx[d];
   ++DP[y][x];
   ++turn;
 }
 if (!fin) turn = -1;
 cout << turn << endl;
//  debug();
}


この記事が気に入ったらサポートをしてみませんか?