Codeforces Round #516 D. Labyrinth
阿新 • • 發佈:2018-11-09
地址: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; }
大佬的做法,用雙端佇列,上下走的放在佇列頭優先走,左右走的放在末尾最後走