地址:http://codeforces.com/contest/1064/problem/D
搜索题,用dfs会超,不能剪枝,因为这个一个cell会被多次访问;
但是一般像遇到像求最短什么的,就用bfs,用bfs也可以,但是要有个优先顺序,因为可能搜索路径会因为之前被搜索过而截断
这个例子:
10 10
10 4
10 9
...*******
.*.*******
.*.*******
.*.*******
.*.*******
.*.*......
.*.*.*****
.*........
.********.
..........
应该修改搜索策略,l+r可搜索宽度较大的先走,那么就要用优先队列了,所以给我个教训,其实宽搜用优先队列就好啊,用的时间又短又好用。。。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
const int N = 2005;
char s[N][N];
bool vis[N][N];
typedef struct Node{
int x,y;
int l,r;
friend bool operator < (const Node &p,const Node &q){
return p.l + p.r < q.l + q.r;
}
}Node;
int n,m,x,y,r,c;
int col[5] = {-1,1,0,0};
int con[5] = {0,0,-1,1};
bool judge(int i,int j)
{
if(i < 1 || j < 1)
return false;
if(i > n || j > m)
return false;
return true;
}
int main()
{
scanf("%d %d",&n,&m);
scanf("%d %d",&r,&c);
scanf("%d %d",&x,&y);
for(int i = 1;i <= n;++i){
scanf("%s",s[i] + 1);
}
memset(vis,false,sizeof(vis));
priority_queue<Node>que;
que.push((Node){r,c,x,y});
vis[r][c] = true;
while(!que.empty())
{
Node tmp = que.top();
que.pop();
int tx = tmp.x,ty = tmp.y;
int l = tmp.l,r = tmp.r;
//cout << tx << " " << ty << " " << l << " " << r << endl;
for(int i = 0;i < 4;++i){
int x1 = tx + col[i];
int y1 = ty + con[i];
if(judge(x1,y1) && !vis[x1][y1] && s[x1][y1] != '*'){
if(i == 2){
if(l - 1 < 0) continue;
vis[x1][y1] = true;
que.push((Node){x1,y1,l - 1,r});
}else if(i == 3){
if(r - 1 < 0) continue;
vis[x1][y1] = true;
que.push((Node){x1,y1,l,r - 1});
}else{
vis[x1][y1] = true;
que.push((Node){x1,y1,l,r});
}
}
}
}
// for(int i = 1;i <= n;++i){
// for(int j = 1;j <= m;++j){
// printf("%d ",vis[i][j]);
// }
// printf("\n");
// }
int sum = 0;
for(int i = 1;i <= n;++i){
for(int j = 1;j <= m;++j){
if(vis[i][j]) sum++;
}
}
printf("%d\n",sum);
return 0;
}
大佬的做法,用双端队列,上下走的放在队列头优先走,左右走的放在末尾最后走