题意:
给定一个迷宫,由 ‘*’ 和 ‘.’ 组成,*表示此处有障碍。给定一个起始点,以及 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;
}