1. 程式人生 > >codeforces+516 Div. 2+D.迷宮+搜尋+雙端佇列

codeforces+516 Div. 2+D.迷宮+搜尋+雙端佇列

題目連結: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;
}