题目链接:http://codeforces.com/contest/1064/problem/D
题目大意:给你一个n*m的矩阵,*是墙,给你初始的坐标,可以向左走x步,向右走y步,上下无数步,问你可能走的最多方块数。
思路:bfs,开一个队列,从起点开始,每搜到一个格子就打上标记。这样是有问题的
,因为我们走到这个格子并不了保证它能走的步数最多。。原因是我们给某些关键点打上标记时,剩余的向左走和向右走的次数也许不是最多的,这样会导致有些格子无法访问。
于是我们改变一下搜索的顺序:用双端队列,向上走或向下走时就push到队头,向左走或向右走时就push到队尾(其实就是先处理一列)。这样我们就能保证给某个格子打上标记时,当前剩余的向左走和向右走的次数是最多的啦。
思考:当时没有想到好的搜索策略。感觉搜索的技巧还有很多要学习的。
#include <bits/stdc++.h>
using namespace std;
char d[2005][2005];
struct node
{
int x, y, l, r;
};
deque<node> dq;
int main()
{
int n, m, x, y, l, r, s=0;
scanf("%d%d",&n,&m);
scanf("%d%d",&x,&y);
scanf("%d%d%*c",&l,&r);
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
scanf("%c",&d[i][j]);
}
scanf("%*c");
}
node p;
p.x=x-1, p.y=y-1, p.l=l, p.r=r;
dq.push_front(p);
d[x-1][y-1]='*';
while(!dq.empty())
{
p=dq.front();
dq.pop_front();
int x, y, l, r;
x=p.x+1, y=p.y;
if(x<n&&d[x][y]=='.')//向上
d[x][y]='*',s++,dq.push_front(node{x, y, p.l, p.r});
x=p.x-1, y=p.y;
if(x>=0&&d[x][y]=='.')//向下
d[x][y]='*',s++,dq.push_front(node{x, y, p.l, p.r});
x=p.x, y=p.y-1;
if(y>=0&&p.l>=1&&p.r>=0&&d[x][y]=='.')//向左
d[x][y]='*',s++,dq.push_back(node{x, y, p.l-1, p.r});
x=p.x, y=p.y+1;
if(y<m&&p.r>=1&&d[x][y]=='.')//向右
d[x][y]='*',s++,dq.push_back(node{x, y, p.l, p.r-1});
}
cout<<s+1<<endl;//起点+1
return 0;
}