HDU 2102 A计划(dfs)

这道题目虽然一看就是dfs,但是感觉太坑了,经过我查了下别人的总结总结出以下几点
  1. 如果第一层是#,第二层也是#,那么就无法进行传送
  2. 起点一定在0,0,0
  3. 题目说是T时刻到达终点,但并不是如此的,可以提前到达,就算比如是13到达,要求14秒那也没事,不要求插值是偶数
  4. 传送下去的点要判断是否经过(这是细节,不是坑点)
  5. 终点不只是在第二层,也可以在第一层
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int n, m, t;
int flag;
char w[2][12][12];
int vis[2][12][12];
int to[4][2]{ 0,1,0,-1,1,0,-1,0 };//写错了
void dfs(int x, int y, int f)
{
	if (flag)
		return;

	if (vis[f][x][y] <= t && w[f][x][y] == 'P')
	{
		flag = 1;
		return;
	}
	if (vis[f][x][y] >= t)
		return;
	int dx, dy;
	for (int i = 0; i<4; i++)
	{
		dx = x + to[i][0];
		dy = y + to[i][1];
		if ((w[f][dx][dy] == '.'|| w[f][dx][dy] == 'P') && !vis[f][dx][dy]&&dx>=0&&dx<n&&dy>=0&&dy<m)
		{
			vis[f][dx][dy] = vis[f][x][y] + 1;
			dfs(dx, dy, f);
			vis[f][dx][dy] = 0;
		}
		if (w[f][dx][dy] == '#' && !vis[f][dx][dy] && !vis[(f+1)%2][dx][dy] && dx >= 0 && dx<n&&dy >= 0 && dy<m)
		{
			vis[f][dx][dy] = vis[f][x][y]+1;
			if (f == 1)
			{
				vis[0][dx][dy] = vis[f][x][y]+1;
				dfs(dx, dy, 0);
				vis[0][dx][dy] = 0;
			}
			else
			{
				vis[1][dx][dy] = vis[f][x][y]+1;
				dfs(dx, dy, 1);
				vis[1][dx][dy] = 0;
			}
			vis[f][dx][dy] = 0;
		}
	}


}
int main()
{
	int N;
	cin >> N;
	while (N--)
	{
		memset(vis, 0, sizeof(vis));
		flag = 0;
		cin >> n >> m >> t;
		for (int i = 0; i<n; i++)
		{
			for (int j = 0; j<m; j++)
			{
				cin >> w[0][i][j];
			}
		}
		for (int i = 0; i<n; i++)
		{
			for (int j = 0; j<m; j++)
			{
				cin >> w[1][i][j];
				if (w[1][i][j] == '#'&&w[0][i][j] == '*')
					w[1][i][j] = '*';
				if (w[0][i][j] == '#'&&w[1][i][j] == '*')
					w[0][i][j] = '*';
				if(w[0][i][j] == '#'&&w[1][i][j] == '#')
					w[0][i][j] = '*', w[1][i][j] = '*';
			}
		}
		int x, y;
		int dx, dy;
		for(int z=0;z<2;z++)
		 for (int i = 0; i<n; i++)
			for (int j = 0; j<m; j++)
			{
				if (w[z][i][j] == 'P')
					dx = i, dy = j;
			}
		x = 0;
		y = 0;
			dfs(x, y, 0);
		if (flag)
			cout << "YES" << endl;
		else
			cout << "NO" << endl;

	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值