NOJ 2076 天神小学

天神小学

时间限制(普通/Java) :  1000 MS/ 3000 MS          运行内存限制 : 65536 KByte
总提交 : 258            测试通过 : 87 

比赛描述

corpse partyblood drive》中有这么一段,班长筱崎亚由美拿到六鬼门的晶石,导致了涅?的暴走,天小的崩溃,靠着幸子的力量才逃出了天小。(剧情什么的不重要)

现在我们假设没有幸子,班长需要靠自己的力量逃出天神小学。可以把天神小学看作是一个二维的迷宫,每一秒都只能从当前位置走到上下左右四个相邻的格子里,因为天小一直在崩溃,所以有很多点是无法行走的。问班长能不能在天小完全崩溃,即t秒内逃出天神小学。



输入

第一行一个整数T,表示数据组数

每组数据第一行输入3个整数nmt分别表示迷宫的行数,列数,以及距离天小崩溃剩余的时间。(3≤n,m≤20,t≤100)

接下来输入n行,每行有一个长度为m的字符串。

其中字符’.’表示可以通行

字符’*’表示无法通行

字符’O’表示出口

字符’X’表示班长的起始位置


输出

若能逃离 输出 "happy end"

否则输出 "bad end"


样例输入

2

5 5 13
.....
.***.
.*X*O
.*.*.
...*.

5 5 14
.....
.***.
.*X*O
.*.*.
...*.

样例输出

bad end
happy end

题目来源

kojimai



本题用DFS或者BFS都可以,我用的是DFS

代码:

/**************************************
*                                     *
*  -*- coding: utf-8 -*-              *
*  @Date    : 2016-04-09 12:22:20     *
*  @Author  : Zeroinger               *
*                                     *
 *************************************/
#include <iostream>
#include <cstring>
#include <cmath>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <cstdio>
#include <algorithm>
using namespace std;
char MAP[21][21];
//方向矩阵
int go[4][2] = {
	{ -1, 0},
	{1, 0},
	{0, -1},
	{0, 1}
};
int ex, ey; //起点
int sx, sy; //终点
int T,m,n,t;
bool DFS(int x, int y, int sum){
	if (x == ex && y == ey && sum <= t)
		return true;
	for (int i = 0; i < 4; i++)
	{
		int nx = x + go[i][0]; 
		int ny = y + go[i][1]; 
		if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue;//判断下一个点是否合法
		if (MAP[nx][ny] != '*')
		{
			MAP[nx][ny] = '*';
			bool flag = DFS(nx, ny, sum + 1);
			if (flag) return true;
			MAP[nx][ny] = '.';
		}
	}
	return false;
}
int main()
{
	 scanf("%d",&T);
	 while(T--)
	 {   
	 	scanf("%d %d %d",&n,&m,&t);
	 	for(int i=0;i<n;i++)
	 	{
	 		cin>>MAP[i];
	 	}
	 	for(int i=0;i<n;i++)
	 	{
	 		for(int j=0;j<m;j++)
	 		{
	 			if(MAP[i][j]=='O') 
	 			{
	 				ex=i;
	 				ey=j;
	 			}
	 			if(MAP[i][j]=='X') 
	 			{
	 				sx=i;
	 				sy=j;
	 			}
	 		}
	 	}
	 	MAP[sx][sy]='*';
	 	if(DFS(sx,sy,0))
	 		printf("happy end\n");
	 	else
	 		printf("bad end\n");
	 }
	 return 0;
}

不过,用BFS好像更快啊

/**************************************
*                                     *
*  -*- coding: utf-8 -*-              *
*  @Date    : 2016-04-09 14:32:10     *
*  @Author  : Zeroinger               *
*                                     *
 *************************************/
#include <iostream>
#include <cstring>
#include <cmath>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <cstdio>
#include <algorithm>
using namespace std;
char MAP[21][21];
bool vis[21][21];
//方向矩阵
int go[4][2] = {
	{ -1, 0},
	{1, 0},
	{0, -1},
	{0, 1}
};
int ex, ey; //起点
int sx, sy; //终点
int T, m, n, t;
struct Node {
	int x, y;
	int cnt;
};
bool BFS()
{
	memset(vis, false, sizeof(vis));
	Node node, tmp;
	queue <Node> q;
	node.x = sx;
	node.y = sy;
	node.cnt = 0;
	q.push(node);
	vis[sx][sy] = true;
	while (!q.empty())
	{
		node = q.front();
		q.pop();
		for (int i = 0; i < 4; i++)
		{
			tmp = node;
			tmp.x = tmp.x + go[i][0];
			tmp.y = tmp.y + go[i][1];
			tmp.cnt++;
			if (tmp.x < 0 || tmp.x >= n || tmp.y < 0 || tmp.y >= m || vis[tmp.x][tmp.y] || MAP[tmp.x][tmp.y] == '*')  continue;
			if (tmp.x == ex && tmp.y == ey && tmp.cnt <= t) return true;
			q.push(tmp);
			vis[tmp.x][tmp.y] = true;
		}
	}
	return false;
}
int main()
{
	scanf("%d", &T);
	while (T--)
	{
		scanf("%d %d %d", &n, &m, &t);
		for (int i = 0; i < n; i++)
		{
			cin >> MAP[i];
		}
		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < m; j++)
			{
				if (MAP[i][j] == 'O')
				{
					ex = i;
					ey = j;
				}
				if (MAP[i][j] == 'X')
				{
					sx = i;
					sy = j;
				}
			}
		}
		if (BFS())
			printf("happy end\n");
		else
			printf("bad end\n");
	}
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值