Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

ค้นหาเส้นทางที่ปลอดภัยที่สุดในเส้นทางที่มีทุ่นระเบิดใน C++


ในปัญหานี้ เราได้รับเมทริกซ์แมท[][] มันกำหนดเส้นทางกับทุ่นระเบิดซึ่งถูกทำเครื่องหมายเป็น 0 หน้าที่ของเราคือค้นหาเส้นทางที่ปลอดภัยที่สั้นที่สุดในพื้นที่ห่างไกลกับทุ่นระเบิด

ขณะเดินลัดเลาะไปตามเส้นทางที่ปลอดภัย เราต้องหลีกเลี่ยงการเดินชิดเซลล์ของทุ่นระเบิด (ซ้าย ขวา ด้านบน และด้านล่าง) เนื่องจากไม่ปลอดภัย

การเคลื่อนไหวที่ถูกต้องทั้งหมดขณะสำรวจเส้นทางคือ −

- Left : mat[i][j] => mat[i-1][j]
- Right : mat[i][j] => mat[i+1][j]
- Top : mat[i][j] => mat[i][j - 1]
- Bottom : mat[i][j] => mat[i][j + 1]

มาดูตัวอย่างเพื่อทำความเข้าใจปัญหากัน

อินพุต

mat[][] = {
   {1, 1, 0, 1},
   {1, 1, 0, 1},
   {1, 1, 1, 1},
   {1, 1, 1, 1}
}

ผลลัพธ์

length of shortest safe path is 7

คำอธิบาย

{
   {1, 1, 0, 1},
   {1, 1, 0, 1},
   {1, 1, 1, 1},
   {1, 1, 1, 1}
}

แนวทางการแก้ปัญหา

วิธีแก้ปัญหาง่ายๆ คือใช้การย้อนรอย แต่ก่อนที่จะหาทางแก้ปัญหา เราจะทำเครื่องหมายทุกเซลล์ที่อยู่ติดกับ alandmine เป็นเซลล์ที่ไม่ปลอดภัย สำหรับการเริ่มต้นเซลล์ในคอลัมน์แรก เราจะไปที่แต่ละเซลล์ที่ปลอดภัยจากตำแหน่งนั้น จากนั้นตรวจสอบว่าเซลล์นั้นนำไปสู่ปลายทาง (เซลล์ใดๆ ในคอลัมน์สุดท้าย) หรือไม่ จากนั้นสำหรับตำแหน่งที่ปลอดภัยทั้งหมดที่สามารถนำไปสู่จุดหมายได้ ให้ค้นหาเส้นทางที่สั้นที่สุดเพื่อไปยังจุดหมาย หากเป็นไปได้ ให้กลับความยาวของเส้นทาง

ผลตอบแทนอื่น -1 แสดงว่าไม่พบเส้นทาง

โปรแกรมเพื่อแสดงการทำงานของโซลูชันของเรา

ตัวอย่าง

#include <bits/stdc++.h>
using namespace std;
#define R 11
#define C 10
int rowNum[] = { -1, 0, 0, 1 };
int colNum[] = { 0, -1, 1, 0 };
bool isSafe(int mat[R][C], int isvisited[R][C], int x, int y){
   if (mat[x][y] == 0 || isvisited[x][y])
      return false;
   return true;
}
bool isValid(int x, int y){
   if (x < R && y < C && x >= 0 && y >= 0)
      return true;
   return false;
}
void unSafeCellsInPath(int mat[R][C]){
   for (int i = 0; i < R; i++){
      for (int j = 0; j < C; j++){
         if (mat[i][j] == 0){
            for (int k = 0; k < 4; k++)
               if (isValid(i + rowNum[k], j + colNum[k]))
            mat[i + rowNum[k]][j + colNum[k]] = -1;
         }
      }
   }
   for (int i = 0; i < R; i++) {
      for (int j = 0; j < C; j++){
         if (mat[i][j] == -1)
            mat[i][j] = 0;
      }
   }
}
void findShortestSafeRouteRec(int mat[R][C], int isvisited[R][C], int i, int j, int &min_dist, int dist){
   if (j == C-1){
      min_dist = min(dist, min_dist);
      return;
   }
   if (dist > min_dist)
      return;
   isvisited[i][j] = 1;
   for (int k = 0; k < 4; k++){
      if (isValid(i + rowNum[k], j + colNum[k]) && isSafe(mat, isvisited, i + rowNum[k], j + colNum[k])){
         findShortestSafeRouteRec(mat, isvisited, i + rowNum[k], j + colNum[k], min_dist, dist + 1);
      }
   }
   isvisited[i][j] = 0;
}
int findShortestSafeRoute(int mat[R][C]){
   int minSafeDist = INT_MAX;
   int isvisited[R][C];
   unSafeCellsInPath(mat);
   for (int i = 0; i < R; i++) {
      if (mat[i][0] == 1) {
         memset(isvisited, 0, sizeof isvisited);
         findShortestSafeRouteRec(mat, isvisited, i, 0, minSafeDist, 0);
         if(minSafeDist == C - 1)
            break;
      }
   }
   if (minSafeDist != INT_MAX)
      return minSafeDist;
   else
      return -1;
}
int main() {
   int mat[R][C] =
   {
      { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
      { 1, 0, 1, 1, 1, 1, 1, 1, 0, 1 },
      { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 },
      { 1, 1, 1, 1, 0, 1, 1, 1, 1, 1 },
      { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
      { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 },
      { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
      { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
      { 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
      { 1, 1, 1, 1, 1, 1, 1, 0, 1, 1 },
      { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 }
   };
   int pathLen = findShortestSafeRoute(mat);
   if(pathLen == -1)
      cout<<"No Safe Path from source to destination possible!";
   else
      cout<<"Shortest Safe route Length is "<<pathLen;
   return 0;
}

ผลลัพธ์

Shortest Safe route Length is 10

ทางเลือกอื่น

วิธีแก้ไขปัญหาอื่นคือการใช้การค้นหาแบบกว้างก่อน เมื่อใช้ thequeue เราจะค้นหาเส้นทางจากคอลัมน์แรกไปยังคอลัมน์สุดท้าย จากนั้นคืนค่าระยะทางต่ำสุดสำหรับเส้นทางจากคอลัมน์แรกไปยังคอลัมน์สุดท้าย

โปรแกรมเพื่อแสดงการทำงานของโซลูชันของเรา

ตัวอย่าง

#include <bits/stdc++.h>
using namespace std;
#define R 11
#define C 10
int rowNum[] = { -1, 0, 0, 1 };
int colNum[] = { 0, -1, 1, 0 };
struct Key{
   int x,y;
   Key(int i,int j){ x=i;y=j;};
};
bool isValid(int x, int y) {
   if (x < R && y < C && x >= 0 && y >= 0)
      return true;
   return false;
}
int findShortestSafeRoute(int mat[R][C]){
   for (int i = 0; i < R; i++) {
      for (int j = 0; j < C; j++) {
         if (mat[i][j] == 0) {
            for (int k = 0; k < 4; k++)
               if (isValid(i + rowNum[k], j + colNum[k]))
                  mat[i + rowNum[k]][j + colNum[k]] = -1;
         }
      }
   }
   for (int i = 0; i < R; i++) {
      for (int j = 0; j < C; j++) {
         if (mat[i][j] == -1)
            mat[i][j] = 0;
      }
   }
   int visited[R][C];
   for(int i=0;i<R;i++){
      for(int j=0;j<C;j++)
         visited[i][j] = -1;
   }
   queue<Key> distQueue;
   for(int i=0;i<R;i++){
      if(mat[i][0] == 1){
         distQueue.push(Key(i,0));
         visited[i][0] = 0;
      }
   }
   while(!distQueue.empty()){
      Key k = distQueue.front();
      distQueue.pop();
      int d = visited[k.x][k.y];
      int x = k.x;
      int y = k.y;
      for (int k = 0; k < 4; k++) {
         int xp = x + rowNum[k];
         int yp = y + colNum[k];
         if(isValid(xp,yp) && visited[xp][yp] == -1 && mat[xp][yp] == 1){
            visited[xp][yp] = d+1;
            distQueue.push(Key(xp,yp));
         }
      }
   }
   int pathLen = INT_MAX;
   for(int i=0;i<R;i++){
      if(mat[i][C-1] == 1 && visited[i][C-1] != -1){
         pathLen = min(pathLen,visited[i][C-1]);
      }
   }
   if(pathLen == INT_MAX)
      return -1;
   else
      return pathLen;
}
int main() {
   int mat[R][C] =
   {
      { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
      { 1, 0, 1, 1, 1, 1, 1, 1, 0, 1 },
      { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 },
      { 1, 1, 1, 1, 0, 1, 1, 1, 1, 1 },
      { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
      { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 },
      { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
      { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
      { 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
      { 1, 1, 1, 1, 1, 1, 1, 0, 1, 1 },
      { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 }
   };
   int pathLen = findShortestSafeRoute(mat);
   if(pathLen == -1)
      cout<<"No Safe Path from source to destination possible!";
   else
      cout<<"Shortest Safe route Length is "<<pathLen;
   return 0;
}

ผลลัพธ์

Shortest Safe route Length is 10