codeforces 1064D 双端队列BFS

双端队列BFS解决的就是路径权值可能为0的图最短路问题,权值为0插入队头,否则插入队尾。

对于这个题,可以看作上下移动的路径的权值为0,左右移动权值为1,而且不能超过规定的步数。

直接广搜求覆盖的点的数目即可。

(场上我一般BFS被hack了)

代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<set>
#include<bitset>
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int maxn=200010;
int a[maxn];
char s[2010][2010];
bool v[2010][2010];
int n,m,r,c,rr,cc;
int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
bool valid(int x,int y){
    return x>=1&&x<=n&&y>=1&&y<=m&&s[x][y]!=‘*‘;
}
struct node{
    int x,y,cnt_l,cnt_r;
};
deque<node> q;
void bfs(void){
    node tmp=(node){r,c,rr,cc};
    node tmp1;
    int ans=0;
    q.push_back(tmp);
    while(!q.empty()){
        tmp=q.front();
        q.pop_front();
        int x=tmp.x,y=tmp.y;
        if(v[x][y])continue;
        v[x][y]=1;
        ans++;
        for(int i=0;i<4;i++){
            tmp1=tmp;
            int tx=x+dx[i];
            int ty=y+dy[i];
            if(valid(tx,ty)){
                if(i==1){
                    if(tmp.cnt_r>0){
                        tmp1.cnt_r--;
                        tmp1.x=tx;
                        tmp1.y=ty;
                        q.push_back(tmp1);
                    }
                }
                else if(i==3){
                    if(tmp.cnt_l>0){
                        tmp1.cnt_l--;
                        tmp1.x=tx;
                        tmp1.y=ty;
                        q.push_back(tmp1);
                    }
                }
                else{
                    tmp1.x=tx;
                    tmp1.y=ty;
                    q.push_front(tmp1);
                }
            }
        }
    }
    printf("%d\n",ans);
}
int main(){
    scanf("%d%d",&n,&m);
    scanf("%d%d",&r,&c);
    scanf("%d%d",&rr,&cc);
    for(int i=1;i<=n;i++)
        scanf("%s",s[i]+1);
    bfs();
}

原文地址:https://www.cnblogs.com/pkgunboat/p/9788895.html

时间: 2024-10-10 10:31:20

codeforces 1064D 双端队列BFS的相关文章

Luogu_P2243 电路维修【题解】 双端队列bfs

题面:https://www.luogu.org/problem/P2243 建边. 对角线有相连路的边权为0,没有的为1. 然后双端队列bfs求最短路. 将边权为0的到的点从队头入队. 边权为1到的点从队尾入队. 这样可以保证最优. 代码如下: #include<bits/stdc++.h> #define int long long using namespace std; const int maxn=510; int T,r,c,dis[maxn][maxn],vis[maxn][ma

8、泛型程序设计与c++标准模板库2.3双端队列容器

双端队列容器是一种放松了访问权限的队列.除了从队列的首部和尾部访问元素外,标准的双端队列也支持通过使用下标操作符"[]"进行直接访问. 它提供了直接访问和顺序访问方法.其头文件为<deque>. 1)双端队列容器的构造函数 有4中形式的构造函数: deque();//构造size()为0的双端队列容器 deque(size_type n,const T& v=T());//初始化大小为n的双端队列,第二个参数是每个元素的初始值,默认为T()构造的对象 deque(c

习题3.26双端队列

#include<stdio.h> #include<stdlib.h> struct Node; struct Queue; typedef struct Node * PtrToNode; typedef struct Queue * PtrToQ; struct Node{ PtrToNode Pre; PtrToNode Next; ElemenType Ele; } struct Queue{ PtrToNode front; PtrToNode rear; }; Ptr

nyoj1117 鸡蛋队列 (双端队列,deque)

题目1117 题目信息 运行结果 本题排行 讨论区 鸡蛋队列 时间限制:1000 ms  |  内存限制:65535 KB 难度:1 描述 将两根筷子平行的放在一起,就构成了一个队列.将带有编号的鸡蛋放到两根筷子之间叫做入队(push),将筷子之间的鸡蛋拿出来叫做出队(pop).但这两种方式有特殊的定义,对于入队,只能将鸡蛋从队列的尾部向里放入:对于出队,只能将鸡蛋从队列的头部向外将鸡蛋拿出来. 将①.②入队: 头____________尾                         ___

算法导论之八(10.1-5单数组实现双端队列)

算法导论第三版P131 题目: 10.1-5 栈插入和删除元素只能在同一端进行,队列的插入操作和删除操作分别在两端进行,与它们不同的,有一种双端队列(deque),其插入和删除操作都可以在两端进行.写出4个时间均为O(1)的过程,分别实现在双端队列插入和删除元素的操作,该队列使用一个数组实现的. 注意点: 1.左右端点指向的位置是类似于队列中的tail端点,是下一个插入操作的位置. 2.然后注意遍历的时候,左端点和右端点的位置关系,有两种可能,所以遍历的方式不一样. 代码: /* * 使用单数组

HDU 4286 Data Handler (双端队列)

Data Handler Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2455    Accepted Submission(s): 616 Problem Description You are in charge of data in a company, so you are called "Data Handler&qu

队列的应用:双端队列

双端队列(Deque:double ended queue)就是一个两端都是结尾的队列.队列的每一端都可以插入数据项和移除数据项.相对于普通队列,双端队列的入队和出队操作在两端都可进行. 双端队列的示意图: left:左端    right:右端 这里我们使用最常用的顺序结构来存储双端队列,为了节省空间,把它首尾相连,构成循环队列.并且规定left指向左端的第一个元素,right指向右端的下一个位置.那么队空的判断则是left==right,队满是(left-1+MAX)%MAX==right或

hdu-5929 Basic Data Structure(双端队列+模拟)

题目链接: Basic Data Structure Time Limit: 7000/3500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 207    Accepted Submission(s): 41 Problem Description Mr. Frog learned a basic data structure recently, which is called

Vijos1834 NOI2005 瑰丽华尔兹 动态规划 单调双端队列优化

设dp[t][x][y]表示处理完前t个时间段,钢琴停留在(x,y)处,最多可以走多少个格子 转移时只需逆着当前倾斜的方向统计len个格子(len为时间区间的长度,len=t-s+1),如果遇到障碍就中断 转移过程可以用单调非递增的双端队列优化 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 const int maxN=202; 6 const int inf=0x3f3f3f3f