【Codeforces Round #516_div2】Labyrinth【迷宫搜索】

题意:

      给定一个迷宫,由 ‘*’ 和 ‘.’ 组成,*表示此处有障碍。给定一个起始点,以及 l 和 r ,l 代表这个点可以向右移动的次数,r表示这个点可以向左移动的次数,求从起始点出发,可以到达多少个不同的点。

思路:

      这是一个典型的迷宫问题,直接用bfs即可解决,主要问题在于如果只用 vis 数组求标记每个点是否走过,如果走过就不再走,这样是会出错的。因为 vis 数组这个点可能被一个到达该点不是最优解的路径所更新,而导致之后的最优解不能再更新这个点。

      因此需要将vis拓展至3维,第一维表示这个点是否被访问过,第二维表示到达这个点的剩下向右移动的次数最大为多少,第三维表示向左移动的最大次数。

      然后用这种方法进行bfs,即可解决问题。

反思:

      打这场cf的时候,宛如一个zz儿童...

      D题出的特别慢,而且写的还是简单的bfs,还写了很久...然后结局就是被吊打,而且D题掉了...

      最近感觉自己水平特别差,看来是非常需要安排一些计划来循序渐进的提高acm水平了,继续加油,保持初心,承认自己的弱小,加油!

代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#define rep(i,a,b) for(int i = a; i <= b; i++)
using namespace std;
const int N = 2000+100;

int n,m;
int ans,l,r,s1,s2;
char a[N][N];
int vis[N][N][4];

struct Tp{
	int p1,p2,l1,r1;
	Tp(int x1,int x2,int x3,int x4) {p1 = x1,p2 = x2,l1 = x3,r1 = x4;}
};

void bfs()
{
	queue< Tp > q;
	while(q.size()) q.pop();
	Tp tmp(s1,s2,l,r);
	q.push(tmp);
//	printf("s:%d %d\n",s1,s2);
	while(q.size())
	{
		//printf("1\n");
		tmp = q.front();
		q.pop();
		int t1 = tmp.p1, t2 = tmp.p2;
		int th1,th2;
		if(tmp.l1 < 0 || tmp.r1 < 0) continue;

		th1 = t1-1, th2 = t2;
		if(th1 >= 1 && th1 <= n && th2 <= m && th2 >= 1 && a[th1][th2] == '.')
		{
			if(vis[th1][th2][0] == -1 || vis[th1][th2][1] < tmp.l1 || vis[th1][th2][2] < tmp.r1)
			{
				if(vis[th1][th2][0] == -1){
					ans++;
				//	printf("%d %d\n",th1,th2);
				} 
				vis[th1][th2][0] = 1;
				vis[th1][th2][1] = max(tmp.l1,vis[th1][th2][1]);
				vis[th1][th2][2] = max(tmp.r1,vis[th1][th2][2]);
				Tp hh(th1,th2,tmp.l1,tmp.r1);
				q.push(hh);
			}
		}

		th1 = t1+1, th2 = t2;
		if(th1 >= 1 && th1 <= n && th2 <= m && th2 >= 1 && a[th1][th2] == '.')
		{
			if(vis[th1][th2][0] == -1 || vis[th1][th2][1] < tmp.l1 || vis[th1][th2][2] < tmp.r1)
			{
				if(vis[th1][th2][0] == -1){
					ans++;
				//	printf("%d %d\n",th1,th2);
				}
				vis[th1][th2][0] = 1;
				vis[th1][th2][1] = max(tmp.l1,vis[th1][th2][1]);
				vis[th1][th2][2] = max(tmp.r1,vis[th1][th2][2]);
				Tp hh(th1,th2,tmp.l1,tmp.r1);
				q.push(hh);
			}
		}

		th1 = t1, th2 = t2+1;
		if(tmp.r1 >= 1 && th1 >= 1 && th1 <= n && th2 <= m && th2 >= 1 && a[th1][th2] == '.')
		{
			if(vis[th1][th2][0] == -1 || vis[th1][th2][1] < tmp.l1 || vis[th1][th2][2] < (tmp.r1-1))
			{
				if(vis[th1][th2][0] == -1){
					ans++;
				//	printf("%d %d\n",th1,th2);
				}
				vis[th1][th2][0] = 1;
				vis[th1][th2][1] = max(tmp.l1,vis[th1][th2][1]);
				vis[th1][th2][2] = max(tmp.r1-1,vis[th1][th2][2]);
				Tp hh(th1,th2,tmp.l1,tmp.r1-1);
				q.push(hh);
			}
		}

		th1 = t1, th2 = t2-1;
		if(tmp.l1 >= 1 && th1 >= 1 && th1 <= n && th2 <= m && th2 >= 1 && a[th1][th2] == '.')
		{
			if(vis[th1][th2][0] == -1 || vis[th1][th2][1] < (tmp.l1-1) || vis[th1][th2][2] < tmp.r1)
			{
				if(vis[th1][th2][0] == -1){
					ans++;
				//	printf("%d %d\n",th1,th2);
				}
				vis[th1][th2][0] = 1;
				vis[th1][th2][1] = max(tmp.l1-1,vis[th1][th2][1]);
				vis[th1][th2][2] = max(tmp.r1,vis[th1][th2][2]);
				Tp hh(th1,th2,tmp.l1-1,tmp.r1);
				q.push(hh);
			}
		}	
	}
}

int main()
{
	scanf("%d%d",&n,&m);
	scanf("%d%d",&s1,&s2);
	scanf("%d%d",&l,&r);
	rep(i,1,n)
		scanf("%s",a[i]+1);
	rep(i,1,n)
		rep(j,1,m) vis[i][j][0] = -1;
	bfs();
	if(vis[s1][s2][0] == -1) ans++;
	printf("%d\n",ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41552508/article/details/83052532
今日推荐