P1143 飘飘乎居士的约会
时间: 1000ms / 空间: 131072KiB / Java类名: Main
背景
一阵狂风吹过
只听“pong”的一声,飘飘乎居士降落了!!!
描述
又是美妙的一天,这天飘飘乎居士要和MM约会,因此他打扮的格外帅气。但是,因为打扮的时间花了太久,离约会的时间已经所剩无几。
幸运的是,现在飘飘乎居士得到了一张n*m的地图,图中左上角是飘飘乎居士的位置,右下角是约会的地点。‘.’代表马路,‘*’代表房屋。飘飘乎居士只能沿着‘.’行走(也就是不能踏入‘*’),而且行走的方向只能为上下左右的相邻格子。为了不让MM等待太久,飘飘乎居士在整个过程中可能会使用一次飘飘神功(也可能不使用,但最多使用一次),使用飘飘神功后,飘飘乎居士可以走进房屋一次(也就是在全程的行走中最多可以走一个‘*’,注意,只有一个);
现在飘飘乎居士想要知道最少需要走多少步,飘飘乎居士才能到达约会的地点。
输入格式
第一行,2个正整数 n和m,表示一个n*m的矩阵
接下来n行,每行m个字符,字符一定为 ’.’ 或者是‘*’ ,分别代表马路和房屋。
输入数据保证左上角和右下角都为‘.’
输出格式
一行,如果可以到达,则输入需要行走的最少步数(飘飘神功也记为一步)
如果不可以到达,则输出‘no’
测试样例1
输入
样例输入1
3 3
.*.
...
...样例输入2
3 3
.**
***
**.
输出
样例输入1
4样例输入2
no
备注
0<N M <=1000飘飘乎居士——violet hill
每个点存两个状态:用过飘飘神功和没有用过。BFS第一次搜到终点的解就是最优解。
因为队列数组开小RE了一个点,差点1A
1 /*by SilverN*/ 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 using namespace std; 8 const int mxn=1010; 9 int mx[5]={0,0,1,0,-1}, 10 my[5]={0,1,0,-1,0}; 11 int n,m; 12 int mp[mxn][mxn]; 13 bool vis[mxn][mxn][2]; 14 int qx[mxn*100],qy[mxn*100],flag[mxn*100],dis[mxn*100]; 15 int hd=0,tl=1; 16 int mxans=300000; 17 void BFS(){ 18 qx[++hd]=1;qy[hd]=1;dis[hd]=0; 19 while(hd<=tl){ 20 for(int i=1;i<=4;i++){ 21 int nx=qx[hd]+mx[i]; 22 int ny=qy[hd]+my[i]; 23 int nflag=flag[hd]; 24 if(nx==n && ny==m){ 25 mxans=min(mxans,dis[hd]+1); 26 continue; 27 } 28 if(nx>0 && nx<=n && ny>0 && ny<=m){ 29 if(!mp[nx][ny]){ 30 if(!vis[nx][ny][nflag]){ 31 vis[nx][ny][nflag]=1; 32 qx[++tl]=nx; 33 qy[tl]=ny; 34 flag[tl]=nflag; 35 dis[tl]=dis[hd]+1; 36 } 37 } 38 else{ 39 if(!nflag){ 40 vis[nx][ny][1]=1; 41 qx[++tl]=nx; 42 qy[tl]=ny; 43 flag[tl]=1; 44 dis[tl]=dis[hd]+1; 45 } 46 } 47 } 48 } 49 hd++; 50 } 51 } 52 int main(){ 53 scanf("%d%d",&n,&m); 54 int i,j; 55 char c[1020]; 56 for(i=1;i<=n;i++){ 57 scanf("%s",c); 58 for(j=1;j<=m;j++) 59 if(c[j-1]==‘*‘)mp[i][j]=1; 60 } 61 BFS(); 62 if(mxans==300000)printf("no\n"); 63 else printf("%d\n",mxans); 64 return 0; 65 }
时间: 2024-10-07 05:18:23