目录
1.Dungeon Master
2.Oil Deposits
3.Find a way
1.Dungeon Master
Sample
Inputcopy | Outputcopy |
---|---|
3 4 5 S.... .###. .##.. ###.###### ##### ##.## ##...##### ##### #.### ####E1 3 3 S## #E# ###0 0 0 | Escaped in 11 minute(s). Trapped! |
这道题与普通的bfs模板题就是地图变成三维的了,其余一律按照模板做法来即可。
下面是AC代码:
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
int h,n,m;
char mp[35][35][35];
struct point{//结构体定义 int z,x,y,step;
};
int v[35][35][35];//是否遍历判断数组
int dx[]={1,-1,0,0,0,0};//枚举6个操作
int dy[]={0,0,1,-1,0,0};
int dz[]={0,0,0,0,1,-1};
int main()
{while(cin>>h>>n>>m){if(h==0&&n==0&&m==0) break;//运行结束标志 int ex,ey,ez,sx,sy,sz;for(int i=1;i<=h;i++){for(int j=1;j<=n;j++){for(int k=1;k<=m;k++){cin>>mp[i][j][k];if(mp[i][j][k]=='S'){sz=i,sx=j,sy=k;//找到起点位置 }if(mp[i][j][k]=='E'){ez=i,ex=j,ey=k;//找到终点位置 } }}}queue<point>q;point st;st.x=sx,st.y=sy,st.z=sz,st.step=0;v[sz][sx][sy]=1;q.push(st);int f=0;while(!q.empty()){point k=q.front();q.pop();if(k.x==ex&&k.y==ey&&k.z==ez)//到达位置 {f=1;cout<<"Escaped in "<<k.step<<" minute(s).\n";//按照格式输出 break;}for(int i=0;i<6;i++){int tx=k.x+dx[i];int ty=k.y+dy[i];int tz=k.z+dz[i];if(tx<1||ty<1||tz<1||tz>h||tx>n||ty>m||mp[tz][tx][ty]=='#'||v[tz][tx][ty]) continue;//错误位置判断 v[tz][tx][ty]=1;point p;p.x=tx,p.y=ty,p.z=tz,p.step=k.step+1;q.push(p);//赋值入队 }}if(f==0){cout<<"Trapped!\n";//走不出 }memset(v,0,sizeof(v));//初始化,防止对下一次数据造成影响 }return 0;
}
2.Oil Deposits
Sample
Inputcopy | Outputcopy |
---|---|
1 1 * 3 5 *@*@* **@** *@*@* 1 8 @@****@* 5 5 ****@ *@@*@ *@**@ @@@*@ @@**@ 0 0 | 0 1 2 2 |
该题需要我们找出有多少种类的油,当两油的相对位置如下
则这两油为同一种类的油,可以用dfs对一油袋周围深搜,搜到的油改为平底,这用每搜一次,对应的不同种类油就可以+1。
下面是AC代码:
#include<cstdio>
#include<iostream>
using namespace std;
char mp[120][120];
int n,m,ans;
int dx[8]={-1,-1,0,1,1,1,0,-1};//操作方向
int dy[8]={0,1,1,1,0,-1,-1,-1};
void dfs(int x,int y)
{if(x<0||y<0||x>=n||y>=m) return;//越界停止搜 if(mp[x][y]=='@'){mp[x][y]='*';for(int i=0;i<8;i++){dfs(x+dx[i],y+dy[i]);//继续搜 }}return;
}
int main()
{while(cin>>n>>m){if(n==0&&m==0) break;ans=0;//初始化 for(int i=0;i<n;i++)cin>>mp[i];for(int i=0;i<n;i++){for(int j=0;j<m;j++){if(mp[i][j]=='@')//发现不同种类油袋 ans++,dfs(i,j);//将与它连通的油袋变为'*' }} cout<<ans<<"\n";}return 0;
}
3.Find a way
Sample
Inputcopy | Outputcopy |
---|---|
4 4 Y.#@ .... .#.. @..M 4 4 Y.#@ .... .#.. @#.M 5 5 Y..@. .#... .#... @..M. #...# | 66 88 66 |
这道题要求我们找到一个Y和M去到一家肯德基汇合的最短时间和,我们可以分别给Y和M定义一个距离数组,为Y和M到相应位置的距离,后面对肯德基的位置比较,找到一个最短距离和。
下面是AC代码:
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
char mp[201][201];
int v[201][201];
int dis1[201][201],dis2[201][201];//定义两个距离数组
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
struct node{int x,y;
};
int bfs(int x,int y,int n,int m,char f)
{queue<node>q;node st;int ans=0;st.x=x,st.y=y;v[x][y]=1;q.push(st);while(!q.empty()){node k=q.front();q.pop();for(int i=0;i<4;i++){int tx=k.x+dx[i];int ty=k.y+dy[i];if(!v[tx][ty]&&mp[tx][ty]!='#'&&tx>=1&&ty>=1&&tx<=n&&ty<=m){v[tx][ty]=1;node p;if(f=='Y') dis1[tx][ty]=dis1[k.x][k.y]+1;//按照f,给相应的距离数组赋值 else dis2[tx][ty]=dis2[k.x][k.y]+1;p.x=tx,p.y=ty;;q.push(p);}}}return ans*11;
}
int main()
{int n,m;while(cin>>n>>m){node kfc[40100];int z=0;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){cin>>mp[i][j];if(mp[i][j]=='@') kfc[++z].x=i,kfc[z].y=j;//找到每家kcf的位置 }}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(mp[i][j]=='Y') {bfs(i,j,n,m,'Y');memset(v,0,sizeof(v));//初始化 }if(mp[i][j]=='M'){bfs(i,j,n,m,'M');memset(v,0,sizeof(v));} }}int ans=1e8;for(int i=1;i<=z;i++){if(dis1[kfc[i].x][kfc[i].y]!=0&&dis2[kfc[i].x][kfc[i].y]!=0)ans=min(ans,dis1[kfc[i].x][kfc[i].y]+dis2[kfc[i].x][kfc[i].y]);//更新最短距离 }cout<<ans*11<<"\n";memset(dis1,0,sizeof(dis1));//初始化 memset(dis2,0,sizeof(dis2));} return 0;
}