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;
}

猜你喜欢

转载自blog.csdn.net/qq_21433411/article/details/83154391
今日推荐