Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<stdio.h>
- #include<queue>
- using namespace std;
- int n,m;
- struct pos{
- int I,J;
- pos operator + (const pos& rhs)const
- {
- return {I + rhs.I , J + rhs.J};
- }
- };
- bool isinbound(pos p){
- return ( (0 <= p.I && p.I < n ) && (0 <= p.J && p.J < m) );
- }
- struct elem{
- int key;
- pos now;
- };
- int min(int a,int b)
- {
- return (a < b ? a : b);
- }
- int main()
- {
- scanf("%d %d",&n,&m);
- char board[n][m+1];
- for(int i = 0 ; i < n ; i ++){
- scanf(" %s",board[i]);
- }
- pos begin , end;
- for(int i = 0 ; i< n ; i ++){
- for(int j = 0 ; j < m ; j ++){
- if(board[i][j] == 'S'){
- begin.I = i;
- begin.J = j;
- }
- if(board[i][j] == 'E'){
- end.I = i;
- end.J = j;
- }
- }
- }
- bool visited[8][n][m]; // J = 1(1<<0) , B = 2(1<<1) , P = 4(1<<2) , JB = 3 , JP = 5 , BP = 6 , JBP = 7
- int dist[8][n][m];
- for(int key = 0 ; key < 8 ; key ++){ //
- for(int i = 0 ; i < n ; i ++){
- for(int j = 0 ; j < m ; j ++){
- visited[key][i][j] = false;
- dist[key][i][j] = 1e9;
- }
- }
- }
- dist[0][begin.I][begin.J] = 0;
- queue<elem> q;
- q.push({0,{begin.I , begin.J} });
- while(!q.empty()){
- int key = q.front().key;
- pos now = q.front().now;
- q.pop();
- /* if(visited[key][now.I][now.J])continue;
- visited[key][now.I][now.J] = true;*/
- // printf("Test at (%d,%d) with #%d key \n",now.I,now.J,key);
- pos move[4] = { {-1,0} , {0,1} , {1,0} , {0,-1} };
- for(int i = 0 ; i < 4 ; i ++){
- pos nxt = now + move[i];
- if(isinbound(nxt))
- {
- // if(visited[key][nxt.I][nxt.J])continue;
- char nxtonB = board[nxt.I][nxt.J];
- if(nxtonB == '#'){
- continue;
- }
- else if(nxtonB == '.' || nxtonB == 'S'){
- if(dist[key][nxt.I][nxt.J] > dist[key][now.I][now.J] + 1){
- dist[key][nxt.I][nxt.J] = dist[key][now.I][now.J] + 1;
- q.push({key,nxt});
- }
- // printf("go to (%d,%d)\n",nxt.I,nxt.J);
- }
- else if(nxtonB == 'j'){ // get j key
- if(dist[key|(1<<0)][nxt.I][nxt.J] > dist[key][now.I][now.J] + 1){
- dist[key|(1<<0)][nxt.I][nxt.J] = dist[key][now.I][now.J] + 1;
- q.push({key|(1<<0),nxt});
- }
- // printf("go to (%d,%d)\n",nxt.I,nxt.J);
- }
- else if(nxtonB == 'b'){ // get b key
- if(dist[key|(1<<1)][nxt.I][nxt.J] > dist[key][now.I][now.J] + 1){
- dist[key|(1<<1)][nxt.I][nxt.J] = dist[key][now.I][now.J] + 1;
- q.push({key|(1<<1),nxt});
- }
- // printf("go to (%d,%d)\n",nxt.I,nxt.J);
- }
- else if(nxtonB == 'p'){ // get p key
- if(dist[key|(1<<2)][nxt.I][nxt.J] > dist[key][now.I][now.J] + 1){
- dist[key|(1<<2)][nxt.I][nxt.J] = dist[key][now.I][now.J] + 1;
- q.push({key|(1<<2),nxt});
- }
- // printf("go to (%d,%d)\n",nxt.I,nxt.J);
- }
- else if(nxtonB == 'J' && (key&(1<<0))){ //have J key
- if(dist[key][nxt.I][nxt.J] > dist[key][now.I][now.J] + 1){
- dist[key][nxt.I][nxt.J] = dist[key][now.I][now.J] + 1;
- q.push({key,nxt});
- }
- // printf("go to (%d,%d)\n",nxt.I,nxt.J);
- }
- else if(nxtonB == 'B' && (key&(1<<1))){ //have B key
- if(dist[key][nxt.I][nxt.J] > dist[key][now.I][now.J] + 1){
- dist[key][nxt.I][nxt.J] = dist[key][now.I][now.J] + 1;
- q.push({key,nxt});
- }
- // printf("go to (%d,%d)\n",nxt.I,nxt.J);
- }
- else if(nxtonB == 'P' && (key&(1<<2))){ //have P key
- if(dist[key][nxt.I][nxt.J] > dist[key][now.I][now.J] + 1){
- dist[key][nxt.I][nxt.J] = dist[key][now.I][now.J] + 1;
- q.push({key,nxt});
- }
- // printf("go to (%d,%d)\n",nxt.I,nxt.J);
- }
- else if(nxtonB == 'E'){
- if(dist[key][nxt.I][nxt.J] > dist[key][now.I][now.J] + 1){
- dist[key][nxt.I][nxt.J] = dist[key][now.I][now.J] + 1;
- }
- // printf("Test goal cost : %d\n",dist[key][nxt.I][nxt.J]);
- break;
- }
- }
- }
- }
- int ans = 1e9;
- for(int i = 0 ; i < 8 ; i ++){
- // printf("checking #%d with %d < %d ? \n",i,dist[i][end.I][end.J],ans);
- ans = min(ans,dist[i][end.I][end.J]);
- }
- printf("%d",(ans == 1e9 ? -1 : ans));
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement