DFS练习——王子救公主

 

一天,蒜头君梦见自己当上了王子,但是不幸的是,自己的公主被可恶的巫婆抓走了。于是蒜头君动用全国的力量得知,自己的公主被巫婆抓进一个迷宫里面。由于全国只有蒜头君自己可以翻越迷宫外的城墙,蒜头君便自己一人走上的拯救自己公主的路途。

碰巧的是巫婆出去了,迷宫也不大,蒜头君可以直接和公主对话,于是两个人便开始相互靠近。每一步移动只能朝着上下左右四个方向走一格,不能走进墙所在的位置。蒜头君救公主心切,一次必须沿着一个方向走两步(允许跨越迷宫中的墙);公主柔弱,一次只能走一步。问在这个迷宫中,蒜头君是否可以救出公主(蒜头君和公主相遇后,就能背着公主逃出迷宫了)。

输入格式

第一行输入两个整数 n(1≤n≤100), m(1≤m≤100) 表示迷宫的行和列。

然后有一个 n×m 的地图,地图由'.''#''w''g'这四个部分组成。'.'表示可以通行的路,'#'表示迷宫的墙,'w'表示王子开始所在的位置,'g'表示公主开始所在的位置。

输出格式

输出王子是不可以救出自己的公主,如果能救出则输出"yes",否则输出"no"

样例输入复制

1 8
w....#.g

样例输出复制

yes

 


思路:

这道题的关键是,需要两次搜索,分别表示王子和公主走过的路

然后看看是否他们可以走过同一个位置

如果可以,说明可以救出

 

代码:

#include<iostream>
using namespace std;
int n,m;
int ax,ay,bx,by;
char s[105][105];
int w[105][105],g[105][105]; //记录王子公主所经过的点 
//int step_2[4][2] = {{2,0},{-2,0},{0,2},{0,-2}};
int step[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
int vis[105][105][3];  //标记是否走过,第三维度表示是公主走的还是王子


void dfs(int x, int y, int tar)
{
	if(s[x][y]  == '#')
		return ;
	if(tar == 2) //王子 
		w[x][y] = 1; //记录王子经过的点 
	if(tar == 1)
		g[x][y] = 1; //记录公主经过的点 
						
	for(int i=0;i<4;i++){
		int tx = x + tar * step[i][0];
		int ty = y + tar * step[i][1];
		if(tx<=0 || tx>n || ty<=0 || ty>m)
			continue;
		if(!vis[tx][ty][tar]){
			vis[tx][ty][tar] = true;
			dfs(tx, ty, tar);	
		}		
	}
	return ;
} 

int main()
{
	std::ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n>>m;
	for(int i=1; i<=n;i++){
		for(int j=1; j<=m;j++){
			cin>>s[i][j];
			if(s[i][j] == 'w'){ //记录王子的坐标 
				ax = i; ay = j;
			}
			if(s[i][j] == 'g'){
				bx = i; by = j;
			}	
		}
	}
	dfs(ax, ay, 2); //由王子进行搜索,标记出所有王子到达的点 
	dfs(bx, by, 1);//由公主进行搜索,标记出所有公主到达的点
	for(int i=1; i<=n;i++){
		for(int j=1; j<=m;j++){//若王子公主能到达同一点,则可以救出 
			if(w[i][j] == g[i][j] && w[i][j] && g[i][j]){
				cout<<"yes"<<endl;
				return 0;
			}
		}
	}
	cout<<"no"<<endl;
	return 0; 
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值