zoukankan      html  css  js  c++  java
  • POJ 2044 Weather Forecast(DFS + 强剪枝)

    题意:

    有一朵2*2的云朵,和一个4*4的地区。被云层覆盖的区域在当天一定有雨下,云层有4种移动方式 。但是规定在城市或者节日期间希望不要下雨,而且一个地方不能有连续7天没下雨。

    思路:

    1. 要保证 16 方块中每个方块都在 7 天内被下过雨,因为云块是 2*2 的,所以则只需保证(0,0)(0,1)(1,0)(1,1)四个角落满足上述要求即可;

    2. 对于云块,每次有 9 种不同的选择,上下左右,走1步2步,或者不动,针对这 9 种情况,深度搜索即可;

    3. 暴力的搜索方法结果就是 TLE,这次采取一种记忆化剪枝的方法,vis[] 标记数组表示:第 k 天,云块处在第 x 位置时,四个角落上面各多少天没被下雨的情况,

       如果被递归树某个分支访问过了,则标记为 true。因为 16 方块,访问密集度很高,如果下次再访问,说明重复,则剪枝。这种方法能有效的降低时间;

    4. 对于某一天的城市情况,则可以用位运算来表示,只需要一个 int 就能满足需求, 最终代码跑到了 110ms ;

    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    struct ST {
        int c00, c01;
        int c10, c11;
        ST() : c00(0), c01(0), c10(0), c11(0) {}
    };
    
    struct POS {
        int x, y;
        POS(int _x, int _y) : x(_x), y(_y) {}
    };
    
    const int dir[9][2] = {{0,0},{-1,0},{-2,0},{0,-1},
                      {0,-2},{1,0},{2,0},{0,1},{0,2}};
    bool vis[370][9][7][7][7][7];
    int day[370], N;
    
    inline int getflag(int r) {
        return 1 << r;
    }
    
    bool judge(int k, const POS& u, const ST& s) {
        if (s.c00 == 7 || s.c01 == 7 || s.c10 == 7 || s.c11 == 7) 
            return false;
    
        int flag = 0;
        int x = u.x, y = u.y;
        flag |= getflag(4*x + y) | getflag(4*x + y+1);
        flag |= getflag(4*(x+1) + y) | getflag(4*(x+1) + y+1);
        if (flag & day[k])
            return false;
    
        if (vis[k][3*x+y][s.c00][s.c01][s.c10][s.c11])
            return false;
        vis[k][3*x+y][s.c00][s.c01][s.c10][s.c11] = true;
        return true;
    }
    
    bool dfs(int k, const POS& u, const ST& state) {
        if (k == N)
            return true;
    
        ST s = state;
        s.c00 += 1, s.c01 += 1;
        s.c10 += 1, s.c11 += 1;
    
        if (u.x == 0 && u.y == 0)
            s.c00 = 0;
        else if (u.x == 0 && u.y == 2)
            s.c01 = 0;
        else if (u.x == 2 && u.y == 0)
            s.c10 = 0;
        else if (u.x == 2 && u.y == 2)
            s.c11 = 0;
    
        if (!judge(k, u, s))
            return false;
    
        for (int i = 0; i < 9; i++) {
            int x = u.x + dir[i][0];
            int y = u.y + dir[i][1];
            if (0 <= x && x < 3 && 0 <= y && y < 3) {
                if (dfs(k + 1, POS(x, y), s))
                    return true;
            }
        }
        return false;
    }
    
    int main() {
        while (scanf("%d", &N) && N) {
            for (int i = 0; i < N; i++) {
                day[i] = 0;
                for (int j = 0; j < 16; j++) {
                    int x;
                    scanf("%d", &x);
                    day[i] <<= 1;
                    day[i] |= x;
                }
                memset(vis[i], false, sizeof(vis[i]));
            }
            ST s;
            if (dfs(0, POS(1, 1), s))
                printf("1\n");
            else
                printf("0\n");
        }
        return 0;
    }
  • 相关阅读:
    Android自定义之仿360Root大师水纹效果
    Android之TextView的Span样式源码剖析
    Android之TextView的样式类Span的使用详解
    随着ScrollView的滑动,渐渐的执行动画View
    仿微信主界面导航栏图标字体颜色的变化
    android自定义之 5.0 风格progressBar
    Android性能优化之内存篇
    Android性能优化之运算篇
    How to install Zabbix5.0 LTS version with Yum on the CentOS 7.8 system?
    How to install Zabbix4.0 LTS version with Yum on the Oracle Linux 7.3 system?
  • 原文地址:https://www.cnblogs.com/kedebug/p/2985693.html
Copyright © 2011-2022 走看看