codeforces+516 Div. 2+D.迷宮+搜尋+雙端佇列
阿新 • • 發佈:2018-11-17
題目連結: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; }