zoukankan      html  css  js  c++  java
  • CF 1064 D. Labyrinth

    D. Labyrinth

    http://codeforces.com/contest/1064/problem/D

    题意:

      n*m的矩阵,只能往左走l次,往右走r次,上下走无限制,问能走到多少个点。

    分析:

      01bfs。

      直接bfs会出现问题,因为一旦打上标记后,下一次无法访问到,但是下一次的状态还更优。

    像这样的样例:

    .....
    .***.
    ...*.
    *.**.
    *.**.
    *....

    做法:用双端队列,向上走或向下走时就push到队头,向左走或向右走时就push到队尾(其实就是先处理一列)。这样我们就能保证给某个格子打上标记时,当前剩余的向左走和向右走的次数是最多这样我们就能保证给某个格子打上标记时,当前剩余的向左走和向右走的次数是最多的啦。

    引用自:dummyummy

    0-1BFS用来解决:边权值为0或1,或者能够转化为这种边权值的最短路问题,时间复杂度为O(E+V).

    0-1BFS,从队列front中去除点u,遍历u的所有边,如果当前边可以进行relax操作,则relax,然后判断level,若level相同,放到队列的front,否则,放到back,队列采用双端队列deque。

    实际上跟最短路挺像。 另外:由于松弛操作的存在,0-1bfs可以去掉vis数组,而且速度会更快。

    引用自:R灬O灬J

    代码:

     1 /*
     2 * @Author: mjt
     3 * @Date:   2018-10-16 21:52:39
     4 * @Last Modified by:   mjt
     5 * @Last Modified time: 2018-10-16 23:03:39
     6 */
     7 #include<cstdio>
     8 #include<algorithm>
     9 #include<cstring>
    10 #include<cmath>
    11 #include<iostream>
    12 #include<cctype>
    13 #include<set>
    14 #include<vector>
    15 #include<queue>
    16 #include<map>
    17 #define fi(s) freopen(s,"r",stdin);
    18 #define fo(s) freopen(s,"w",stdout);
    19 using namespace std;
    20 typedef long long LL;
    21 
    22 inline int read() {
    23     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
    24     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
    25 }
    26 
    27 const int N = 2005;
    28 
    29 struct Node{
    30     int x, y, l, r;
    31     Node() {}
    32     Node(int _1,int _2,int _3,int _4) { x = _1, y = _2, l = _3, r = _4; }
    33 };
    34 
    35 int n, m, sx, sy, L, R;
    36 bool vis[N][N];
    37 char s[N][N];
    38 deque <Node> q;
    39 
    40 int dx[10] = {1, -1, 0, 0};
    41 int dy[10] = {0, 0, 1, -1};
    42 
    43 void bfs() {
    44     vis[sx][sy] = 1;
    45     q.push_front(Node(sx, sy, L, R));
    46     while (!q.empty()) {
    47         Node now = q.front(); q.pop_front();
    48         for (int i=0; i<4; ++i) {
    49             int x = now.x + dx[i], y = now.y + dy[i];
    50             if (x >= 1 && x <= n && y >= 1 && y <= m && !vis[x][y] && s[x][y] == '.') {
    51                 if (i == 0 || i == 1) vis[x][y] = 1, q.push_front(Node(x, y, now.l, now.r)); // vis的位置!!! 
    52                 else if (i == 2 && now.r) vis[x][y] = 1, q.push_back(Node(x, y, now.l, now.r - 1));
    53                 else if (i == 3 && now.l) vis[x][y] = 1, q.push_back(Node(x, y, now.l - 1, now.r));
    54             }
    55         }
    56     }
    57 }
    58 int main() {
    59     n = read(), m = read(), sx = read(), sy = read(), L = read(), R = read();
    60     for (int i=1; i<=n; ++i) scanf("%s", s[i] + 1);
    61     bfs();
    62     int ans = 0;
    63     for (int i=1; i<=n; ++i)
    64         for (int j=1; j<=m; ++j) ans += vis[i][j];
    65     cout << ans;
    66     return 0;
    67 }
  • 相关阅读:
    物料主档的屏幕增强
    删除请求号(网上转载)
    Echarts X轴内容过长自动隐藏,鼠标移动上去显示全部名称方法
    mscms学习
    java 基础(泛型)
    java 基础(枚举类)
    java 基础(抽象类)
    java 基础(单例)
    android项目杂记
    Android Studio--学习系列(3)发版
  • 原文地址:https://www.cnblogs.com/mjtcn/p/9801371.html
Copyright © 2011-2022 走看看