題目:有一個 n × m 的迷宮,其中 . 表示空地, * 表示障礙物。除此之外,有 qq 個單向傳送門:如果進入格子 (a_i,b_i)(ai,bi) ,那么會被立即傳送到 (c_i,d_i)(ci,di) 。保證每個點至多是一個傳送門的入口。
如果傳送門最終傳送到障礙物上,那么將會卡在障礙物上不能移動。
在傳送門內部傳送的花費是 0,在空地上每次可以往周圍四個格子移動,花費是 1。(因為傳送門內部花費為0,所以要比較花費的多少)
如果無法到達終點,輸出 “No solution”

通過com數組記錄這個是第幾個傳送門,這個數值唯一,通過door數組利用數值找到這個傳送門傳到的橫坐標和縱坐標(door[傳送門][0] 和 door[傳送門][1])
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define N 1010 5 #define inf 0x3f3f3f3f 6 char g[N][1010];//地圖 7 int com[N][N] = { 0 };//用來標記是否為傳送門 8 int door[N][3] = { 0 };//用來記錄傳送到哪door[i][0]和door[i][1]分別用來x,y 9 int vis[N][N];//當到這一點時所用的花費 10 int dir[2][4] = { -1,+1,0,0,0,0,-1,+1 }; 11 int x, y; 12 int n, m; 13 int ans = inf; 14 struct node 15 { 16 int x, y, num; 17 18 }; 19 int bfs(int p, int q) 20 { 21 queue<node>que; 22 node w; 23 w.x = p, w.y = q, w.num = 0; 24 vis[p][q] = 0; 25 que.push(w); 26 while (!que.empty()) 27 { 28 node w; 29 w = que.front(); 30 que.pop(); 31 int pp = w.x, qq = w.y; 32 //cout<<"sjbd "<<pp<<" "<<qq<<" "<<w.num<<endl; 33 if(pp==x&&qq==y) 34 { 35 return w.num; 36 } 37 int u = com[pp][qq]; 38 // cout<<"u="<<u<<endl; 39 if (u != 0) 40 { 41 int ppp = door[u][0]; 42 int qqq = door[u][1]; 43 if (g[ppp][qqq] == '.'&&w.num<vis[ppp][qqq]) 44 {//傳送到的點不是障礙且比較這么走的花費小 45 vis[ppp][qqq] = w.num; 46 node e = w; 47 e.x = ppp, e.y = qqq; 48 que.push(e); 49 } 50 } 51 else 52 { 53 for (int i = 0; i < 4; i++) 54 { 55 int xx = w.x+dir[0][i], yy = w.y+dir[1][i]; 56 if (vis[xx][yy]>w.num+1&& g[xx][yy] == '.'&&xx >= 1 && xx <= n && yy >= 1 && yy <= m) 57 { 58 // cout << xx << " " << yy << endl; 59 node e=w; 60 e.num += 1; 61 e.x = xx, e.y = yy; 62 vis[xx][yy] = w.num+1; 63 que.push(e); 64 } 65 } 66 } 67 68 } 69 return inf; 70 } 71 int main() 72 { 73 ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); 74 fill(vis[0],vis[0]+(N*N),inf); 75 cin >> n >> m; 76 for (int i = 1; i <= n; i++) 77 { 78 for (int j = 1; j <= m; j++) 79 cin >> g[i][j]; 80 } 81 int p; 82 cin >> p; 83 while (p--) 84 { 85 int x1, y1, x2, y2; 86 cin >> x1 >> y1 >> x2 >> y2; 87 com[x1][y1] = p+1; 88 //因為P值不會重復,所以可以用來標記是否為傳送門的同時可以同時看他所傳送到的地方 89 door[p+1][0] = x2; 90 door[p+1][1] = y2; 91 } 92 cin >> x >> y; 93 ans=bfs(1, 1); 94 if(ans!=inf) 95 cout<<ans<<endl; 96 else 97 cout<<"No solution"<<endl; 98 return 0; 99 }
