zoukankan      html  css  js  c++  java
  • hdu 4770 Lights Against Dudely(回溯)

    题目链接:hdu 4770 Lights Against Dudely

    题目大意:在一个N*M的银行里。有N*M个房间,‘#’代表牢固的房间,‘.‘代表的是脆弱的房间。脆弱的房间个数不会超过15个,如今为了确保安全,要在若干个脆弱的房间上装灯。普通的灯是照亮{0, 0}, {-1, 0}, {0, 1}(和题目中坐标有点出入)。然后能够装一个特殊的,能够照耀

    • { {0, 0}, {0, 1}, {1, 0} },
    • { {0, 0}, {-1, 0}, {0, -1} },
    • { {0, 0}, {0, -1}, {1, 0} }
      同一个房间不能够装两栈灯,灯光不能照耀牢固的房间,问说最少须要多少栈灯。

    解题思路:dfs+剪枝。暴力枚举放特殊灯的位置,然后将脆弱房间依照i坐标大放前面,相等的将j坐标小的方前面,这样做是为了dfs的时候剪枝,仅仅要碰到一个房间不能放就返回。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    const int maxn = 200;
    const int maxv = 20;
    const int INF = 0x3f3f3f3f;
    const int dir[4][3][2] = { { {0, 0}, {-1, 0}, {0, 1} },
                               { {0, 0}, {0, 1}, {1, 0} },
                               { {0, 0}, {-1, 0}, {0, -1} },
                               { {0, 0}, {0, -1}, {1, 0} }
                            };
    
    int ans;
    int n, N, M, x[maxv], y[maxv], c[maxv];
    int v[maxn+5][maxn+5];
    char g[maxn+5][maxn+5];
    
    inline int judge (int xi, int yi, const int d[3][2]) {
    
        for (int i = 0; i < 3; i++) {
            int p = xi + d[i][0];
            int q = yi + d[i][1];
    
            if (p <= 0 || p > N)
                continue;
    
            if (q <= 0 || q > M)
                continue;
    
            if (g[p][q] == '#')
                return 0;
        }
        return 1;
    }
    
    inline void set (int xi, int yi, const int d[3][2], int type) {
        for (int i = 0; i < 3; i++) {
            int p = xi + d[i][0];
            int q = yi + d[i][1];
    
            if (p <= 0 || p > N)
                continue;
    
            if (q <= 0 || q > M)
                continue;
    
            v[p][q] = type;
        }
    }
    
    void init () {
        n = 0;
        for (int i = 1; i <= N; i++)
            scanf("%s", g[i] + 1);
    
        for (int i = N; i; i--) {
            for (int j = 1; j <= M; j++) {
                if (g[i][j] == '.') {
                    x[n] = i;
                    y[n] = j;
                    n++;
                }
            }
        }
    
        memset(c, 0, sizeof(c));
        for (int i = 0; i < n; i++)
            c[i] = judge(x[i], y[i], dir[0]);
    }
    
    /*
       int solve (int spi, int id) {
    
       memset(v, 0, sizeof(v));
       int ans = INF;
       for (int s = 0; s < (1<<n); s++) {
    
       bool flag = true;
       for (int i = 0; i < n; i++) {
       if (s&(1<<i) && (c[i] == 0 || i == spi)) {
       flag = false;
       break;
       }
       }
    
       if (flag) {
       int light = 0;
       int tmp = set(x[spi], y[spi], dir[id], 1);
    
       for (int i = 0; i < n; i++) {
       if (s&(1<<i)) {
       light++;
       tmp += set(x[i], y[i], dir[0], 1);
       }
       }
    
       if (tmp == n)
       ans = min(ans, light);
    
       memset(v, 0, sizeof(v));
       }
       }
       return ans+1;
       }
       */
    
    void dfs (int d, int f, int cnt) {
    
        if (cnt >= ans)
            return;
    
        if (d == n) {
            ans = cnt;
            return;
        }
    
        if (v[x[d]][y[d]])
            dfs (d + 1, f, cnt);
    
        if (c[d] && d != f) {
            set(x[d], y[d], dir[0], 1);
            dfs (d + 1, f, cnt+1);
            set(x[d], y[d], dir[0], 0);
        }
    }
    
    int main () {
        while (scanf("%d%d", &N, &M) == 2 && N + M) {
            init();
    
            ans = INF;
            if (n == 0)
                ans = 0;
    
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < 4; j++) {
                    if (judge (x[i], y[i], dir[j])) {
                        memset(v, 0, sizeof(v));
    
                        set(x[i], y[i], dir[j], 1);
    
                        dfs(0, i, 1);
    
                        set(x[i], y[i], dir[j], 0);
                    }
                }
            }
    
            if (ans == INF)
                printf("-1
    ");
            else
                printf("%d
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    python计算机视觉项目实践
    Codeforces Round #256 (Div. 2) B (448B) Suffix Structures
    SonarLint插件的安装与使用
    后缀表达式求值
    有用代码段2
    提高Java代码质量的Eclipse插件之Checkstyle的使用具体解释
    Intellij Idea搭建Spark开发环境
    代码备忘, TODO宏实现
    浏览器自己主动填表安全漏洞:查看浏览器保存的password
    PDO 查询mysql返回字段整型变为String型解决方法
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/6731894.html
Copyright © 2011-2022 走看看