藍橋杯演算法提高 學霸的迷宮
阿新 • • 發佈:2019-02-03
問題描述 學霸搶走了大家的作業,班長為了幫同學們找回作業,決定去找學霸決鬥。但學霸為了不要別人打擾,住在一個城堡裡,城堡外面是一個二維的格子迷宮,要進城堡必須得先通過迷宮。因為班長還有妹子要陪,磨刀不誤砍柴功,他為了節約時間,從線人那裡搞到了迷宮的地圖,準備提前計算最短的路線。可是他現在正向妹子解釋這件事情,於是就委託你幫他找一條最短的路線。輸入格式 第一行兩個整數n, m,為迷宮的長寬。
接下來n行,每行m個數,數之間沒有間隔,為0或1中的一個。0表示這個格子可以通過,1表示不可以。假設你現在已經在迷宮座標(1,1)的地方,即左上角,迷宮的出口在(n,m)。每次移動時只能向上下左右4個方向移動到另外一個可以通過的格子裡,每次移動算一步。資料保證(1,1),(n,m)可以通過。輸出格式 第一行一個數為需要的最少步數K。
第二行K個字元,每個字元∈{U,D,L,R},分別表示上下左右。如果有多條長度相同的最短路徑,選擇在此表示方法下字典序最小的一個。樣例輸入Input Sample 1:
3 3
001
100
110
Input Sample 2:
3 3
000
000
000樣例輸出Output Sample 1:
4
RDRD
Output Sample 2:
4
DDRR資料規模和約定 有20%的資料滿足:1<=n,m<=10
有50%的資料滿足:1<=n,m<=50
接下來n行,每行m個數,數之間沒有間隔,為0或1中的一個。0表示這個格子可以通過,1表示不可以。假設你現在已經在迷宮座標(1,1)的地方,即左上角,迷宮的出口在(n,m)。每次移動時只能向上下左右4個方向移動到另外一個可以通過的格子裡,每次移動算一步。資料保證(1,1),(n,m)可以通過。輸出格式 第一行一個數為需要的最少步數K。
第二行K個字元,每個字元∈{U,D,L,R},分別表示上下左右。如果有多條長度相同的最短路徑,選擇在此表示方法下字典序最小的一個。樣例輸入Input Sample 1:
3 3
001
100
110
Input Sample 2:
3 3
000
000
000樣例輸出Output Sample 1:
4
RDRD
Output Sample 2:
4
DDRR資料規模和約定 有20%的資料滿足:1<=n,m<=10
有50%的資料滿足:1<=n,m<=50
有100%的資料滿足:1<=n,m<=500。
程式碼:
#include <bits/stdc++.h> using namespace std; const int maxn=505; char maze[maxn][maxn]; bool mark[maxn][maxn]; struct N{ int x,y; int t; string s; }; queue<N> Q; int dir[4][2]={{1,0},{0,-1},{0,1},{-1,0}}; char dic[4]={'D','L','R','U'}; void bfs(int n,int m){ while(!Q.empty()){ N now=Q.front(); if(now.x==n-1&&now.y==m-1) printf("%d\n%s\n",now.t,now.s.c_str()); for(int i=0;i<4;i++){ int nx=now.x+dir[i][0]; int ny=now.y+dir[i][1]; if(nx<0||nx>=n||ny<0||ny>=m) continue; if(maze[nx][ny]=='1') continue; if(mark[nx][ny]==true) continue; N tmp; tmp.x=nx;tmp.y=ny;tmp.t=now.t+1;tmp.s=now.s+dic[i]; Q.push(tmp); mark[nx][ny]=true; } Q.pop(); } } int main(){ int n,m; scanf("%d%d",&n,&m); for(int i=0;i<n;i++) scanf("%s",maze[i]); for(int i=0;i<n;i++) for(int j=0;j<m;j++) mark[i][j]=false; mark[0][0]=true; N tmp; tmp.x=0;tmp.y=0;tmp.t=0;tmp.s=""; Q.push(tmp); bfs(n,m); return 0; }