DFS/BFS(解决炸弹人)

问题省略……

DFS解决炸弹人

#include<cstdio>
#include<iostream>
using namespace std;
char a[20][21];//用来存储地图 
int book[20][20],maxn,mx,my,n,m;
int getnum(int i,int j) {
	int x,y,sum=0;//sum用来计数(可以消灭的敌人总数,所以初始化为0) 
				//将坐标i、j复制到两个新变量x、y中,以便之后向上下左右四个方向统计可以消灭的敌人数 
	x=i,y=j;
	while(a[x][y]!='#') {	//判断的点是否为墙,不是墙就继续 
		if(a[x][y]=='G')	//如果当前的点是敌人,则进行计数 
			sum++;
		x--;				//继续向上统计 
	}
	
	x=i,y=j;
	while(a[x][y]!='#') {
		if(a[x][y]=='G')
			sum++;
		x++;				//继续向下统计
	}
	
	x=i,y=j;
	while(a[x][y]!='#') {
		if(a[x][y]!='#')
			sum++;
		y--;				//继续向左统计
	}
	
	x=i,y=j;
	while(a[x][y]!='#') {
		if(a[x][y]=='G')
			sum++;
		y++;				//继续向统计
	}
}

void dfs(int x,int y) {
		//定义一个用于表示走的方向的数组 
		int next[4][2]={
						{0,1},//向右 
						{1,0},//向下 
						{0,-1},//向左 
						{-1,0}};//向上 	
		
		int sum=getnum(x,y);				 
		if(sum>maxn) {
			 maxn=sum;
			 mx=x;
			 my=y;
		}				
		
		int tx,ty;
		for(int k=0;k<=3;k++) {
			tx=x+next[k][0];
			ty=y+next[k][1];
			
			if(tx<0 || tx>n-1 || ty<0 ||ty >m-1)
				continue;
			
			if(a[tx][ty]=='.' && book[tx][ty]==0) {
				book[tx][ty]=1;
				dfs(tx,ty);
			}
		} 
		return ;
	}
int main() {
	
	int startx,starty;
	cin>>n>>m>>startx>>starty;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			cin>>a[i][j];
	
	book[startx][starty]=1;
	maxn=getnum(startx,starty);
	mx=startx;
	my=starty;
	dfs(startx,starty);	
	printf("%d %d %d",mx,my,maxn);
	getchar();getchar();
	return 0; 
	
}


BFS解决炸弹人

#include<cstdio>
#include<iostream>
using namespace std;
struct note {
	int x;
	int y;
};
char a[20][20];//用来存储地图 
int getnum(int i,int j) {
	int x,y,sum=0;//sum用来计数(可以消灭的敌人总数,所以初始化为0) 
				//将坐标i、j复制到两个新变量x、y中,以便之后向上下左右四个方向统计可以消灭的敌人数 
	x=i,y=j;
	while(a[x][y]!='#') {	//判断的点是否为墙,不是墙就继续 
		if(a[x][y]=='G')	//如果当前的点是敌人,则进行计数 
			sum++;
		x--;				//继续向上统计 
	}
	
	x=i,y=j;
	while(a[x][y]!='#') {
		if(a[x][y]=='G')
			sum++;
		x++;				//继续向下统计
	}
	
	x=i,y=j;
	while(a[x][y]!='#') {
		if(a[x][y]!='#')
			sum++;
		y--;				//继续向左统计
	}
	
	x=i,y=j;
	while(a[x][y]!='#') {
		if(a[x][y]=='G')
			sum++;
		y++;				//继续向右统计
	}
	
	return sum;
}
 
int main() {
	struct note que[401];
	int book[20][20]={0};
	
	//定义一个用于表示走的方向的数组 
	int next[4][2]={
					{0,1},//向右 
					{1,0},//向下 
					{0,-1},//向左 
					{-1,0}};//向上 
	
	int n,m,startx,starty;
	cin>>n>>m>>startx>>starty;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			cin>>a[i][j];
			
	
	//队列初始化  
	int head=1;
	int tail=1;
	//往队列插入迷宫入口坐标 
	que[tail].x=startx;
	que[tail].y=starty;
	tail++;
	book[startx][starty]=1;
	
	int	max=getnum(startx,starty); //当前点可以消灭的敌人数 
	int mx=startx;					//当前点的横坐标 
	int my=starty;					//当前点的纵坐标 
	
	int tx,ty;
	
	while(head<tail) {	//当队列不空时候循环 
		for(int k=0;k<=3;k++) {
			//计算下一点坐标
			tx=que[head].x+next[k][0];
			ty=que[head].y+next[k][1];
			
			//判断是否越界 
			if(tx<0 || tx>n-1 || ty<0 || ty>m-1)
				continue;
			
			//判断是否为障碍物 或者已经在路径中 
			if(a[tx][ty]=='.' && book[tx][ty]==0) {
				book[tx][ty]=1;	//把这个点标记为走过,注意宽搜每个点只入列一次,所以和深搜不同,不需要将book数组还原 
				//插入新的点到队列中 
				que[tail].x=tx;
				que[tail].y=ty;
				//que[tail].f=head;//因为这个点是从head拓展而来,所以它的父亲是head,本题目不需要求路径,因此本句可以省略 
				//que[tail].s=que[head].s+1;
				tail++;
			
				int sum=getnum(tx,ty);
			
				if(sum>max) {	//如果当前统计出所能消灭的敌人数大于max,则更新max,并用mx和my记录该点坐标 
					max=sum;
					mx=tx;
					my=ty;
				} 
			}
		}
		head++;//此地方不能忘记,当一个点拓展结束,head++才能对后面的点再进行拓展 
	} 
	

	printf("%d %d %d",mx,my,max);
	getchar();getchar();
	return 0; 
	
}

节选自啊哈磊的《啊哈!算法》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值