2020 藍橋杯大學 B 組省賽模擬賽(一)——迷宮html
別人寫的其餘題題解node
題目:有一個 n × m 的迷宮,其中 .
表示空地, *
表示障礙物。除此以外,有 qq 個單向傳送門:若是進入格子 (a_i,b_i)(ai,bi) ,那麼會被當即傳送到 (c_i,d_i)(ci,di) 。保證每一個點至可能是一個傳送門的入口。ios
若是傳送門最終傳送到障礙物上,那麼將會卡在障礙物上不能移動。c++
在傳送門內部傳送的花費是 0,在空地上每次能夠往周圍四個格子移動,花費是 1。(由於傳送門內部花費爲0,因此要比較花費的多少)數組
若是沒法到達終點,輸出 「No solution」spa
經過com數組記錄這個是第幾個傳送門,這個數值惟一,經過door數組利用數值找到這個傳送門傳到的橫座標和縱座標(door[傳送門][0] 和 door[傳送門][1])3d
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 }