【原创】浅谈搜索-中(dfs)(红与黑,Dungeon Master)

64 篇文章 11 订阅

之前讲了几道dfs,现在我们再来讲几道dfs。

1818:红与黑


总时间限制: 
1000ms 
内存限制: 
65536kB
描述
有一间长方形的房子,地上铺了红色、黑色两种颜色的正方形瓷砖。你站在其中一块黑色的瓷砖上,只能向相邻的黑色瓷砖移动。请写一个程序,计算你总共能够到达多少块黑色的瓷砖。
输入
包括多个数据集合。每个数据集合的第一行是两个整数W和H,分别表示x方向和y方向瓷砖的数量。W和H都不超过20。在接下来的H行中,每行包括W个字符。每个字符表示一块瓷砖的颜色,规则如下
1)‘.’:黑色的瓷砖;
2)‘#’:白色的瓷砖;
3)‘@’:黑色的瓷砖,并且你站在这块瓷砖上。该字符在每个数据集合中唯一出现一次。
当在一行中读入的是两个零时,表示输入结束。
输出
对每个数据集合,分别输出一行,显示你从初始位置出发能到达的瓷砖数(记数时包括初始位置的瓷砖)。
样例输入
6 9 
....#. 
.....# 
...... 
...... 
...... 
...... 
...... 
#@...# 
.#..#. 
0 0
样例输出
45
当看到“最”,或者“一共”的时候,就可以用dfs。

这道题也是如此,只需要不断地走,走到天荒地老,走到世界末日无路可走,然后每走到一个点就把它标记一下,最后再数有几个标记就可以了,详见代码:

#include<cstdio>
#include<cstring>
char a[101][101];
int k,m,n,temp,begina,beginb,maxn;
int dr[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
int vis[101][101];
void guessing(int i,int j)
{
	if(i>=m || j>=n || i<0 || j<0 || vis[i][j] || a[i][j]=='#') return;
	if(a[i][j]=='.') temp++;
	if(temp>=maxn) maxn=temp;
	vis[i][j]=1;
	for(int p=0;p<=3;p++)
	{
		guessing(i+dr[p][0],j+dr[p][1]);
	}
}
int main()
{
	while(1)
	{
		memset(a,0,sizeof(a));
		memset(vis,0,sizeof(vis));
		temp=0,maxn=0;
			
		scanf("%d %d",&n,&m);
		
		if(m==n && n==0) 
			break;
			
		for(int i=0;i<m;i++)
			scanf("%s",a[i]);
		
		for(int i=0;i<m;i++)
			for(int j=0;j<n;j++)
				if(a[i][j]=='@')
					begina=i,beginb=j,a[i][j]='.';
			
		guessing(begina,beginb);
		printf("%d\n",maxn);
	}
}
=_=

不知道说什么了

那就再来一道题吧:

1253:Dungeon Master

总时间限制: 
1000ms 
内存限制: 
65536kB
描述
You are trapped in a 3D dungeon and need to find the quickest way out! The dungeon is composed of unit cubes which may or may not be filled with rock. It takes one minute to move one unit north, south, east, west, up or down. You cannot move diagonally and the maze is surrounded by solid rock on all sides. 

Is an escape possible? If yes, how long will it take? 
输入
The input consists of a number of dungeons. Each dungeon description starts with a line containing three integers L, R and C (all limited to 30 in size). 
L is the number of levels making up the dungeon. 
R and C are the number of rows and columns making up the plan of each level. 
Then there will follow L blocks of R lines each containing C characters. Each character describes one cell of the dungeon. A cell full of rock is indicated by a '#' and empty cells are represented by a '.'. Your starting position is indicated by 'S' and the exit by the letter 'E'. There's a single blank line after each level. Input is terminated by three zeroes for L, R and C.
输出
Each maze generates one line of output. If it is possible to reach the exit, print a line of the form 
Escaped in x minute(s).

where x is replaced by the shortest time it takes to escape. 
If it is not possible to escape, print the line 
Trapped!
样例输入
3 4 5
S....
.###.
.##..
###.#

#####
#####
##.##
##...

#####
#####
#.###
####E

1 3 3
S##
#E#
###

0 0 0
样例输出
Escaped in 11 minute(s).
Trapped!
题目大意:

一觉醒来,你发现自己来到了一个三维迷宫。你不仅跑得飞快,而且跳的很


高,每次可以花一分钟往前后左右走一格,上下跳一楼。你要花多久才能逃出去呢?

输入迷宫地图,S代表起点,E代表终点。

输出“

Escaped in 11 minute(s).
Trapped!
”,表示在11分钟内跑出迷宫或逃不出去。


如果你掌握了dfs,那么这道题对你来说就是一道水题了。只需定义一个三维数组,走的时候加两个方向就可以了。

详见代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<stack>
using namespace std;
const int maxn=50*50*50;
int dr[6][3]={{1,0,0},{0,1,0},{0,0,1},{-1,0,0},{0,-1,0},{0,0,-1}};  
int m,n,k,h,t,x,y,z,xx,yy,zz,step,begina,beginb,beginc,enda,endb,endc,p;  
char a[50][50][50];  
struct Epic
{  
    int e,f,g,step;  
}q[maxn];  
void init()
{
	h=0; t=1; p=0;  
	q[t].e=begina;
	q[t].f=beginb;
	q[t].g=beginc;
	q[t].step=1;  
}
int main()
{  
	while(1+1==2)
	{
		scanf("%d %d %d",&k,&m,&n);
		if(k==0 && m==0 && n==0) break;
		for(int ti=0;ti<k;ti++)
			for(int i=0;i<m;i++)
				for(int j=0;j<n;j++)
				{  			
					cin>>a[ti][i][j];
					if(a[ti][i][j]=='S') begina=i,beginb=j,beginc=ti;  
					if(a[ti][i][j]=='E') enda=i,endb=j,endc=ti;  
				}  
		init(); 
		while(h<t)
		{  
			h++;  
			if(p) break;  
			xx=q[h].e; yy=q[h].f; zz=q[h].g;
			step=q[h].step;  
			for(int i=0;i<6;i++)
			{  
				x=xx+dr[i][0],y=yy+dr[i][1],z=zz+dr[i][2];  
				if(x>=0 && x<m && y>=0 && y<n && z<k && z>=0 && a[z][x][y]!='#')
				{  
					t++;  
					q[t].e=x,q[t].f=y,q[t].g=z,q[t].step=step+1;  
					if(x==enda && y==endb && z==endc) 
					{
						printf("Escaped in %d minute(s).\n",step);
						p=1;
						break;
					}  
					a[z][x][y]='#';  
				}  
			}  
		}  
		if(p==0) printf("Trapped!\n");  
	}
	return 
就这样吧。





















咿呀咿呀哟








  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值