• 状态压缩 + 暴力 HDOJ 4770 Lights Against Dudely


    题目传送门

    题意:有n*m的房间,'.'表示可以被点亮,'#'表示不能被点亮,每点亮一个房间会使旁边的房间也点亮,有意盏特别的灯可以选择周围不同方向的房间点亮。问最少需要多少灯使得所有房间点亮

    分析:需要被点亮的房间最多只有15个,所以考虑状压,然后暴力枚举选择哪一个当作特殊灯和枚举选择哪个方向使旁边的房间亮,注意清空vis数组需要优化,memset超时。上交6分钟1Y,Orz。。。额,看错榜了,最快的19分钟,而且这不是第一道水题,汗

    /************************************************
     * Author        :Running_Time
     * Created Time  :2015/10/22 星期四 18:25:25
     * File Name     :A.cpp
     ************************************************/
    
    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <queue>
    #include <deque>
    #include <stack>
    #include <list>
    #include <map>
    #include <set>
    #include <bitset>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    #define lson l, mid, rt << 1
    #define rson mid + 1, r, rt << 1 | 1
    typedef long long ll;
    const int N = 2e2 + 10;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1e9 + 7;
    const double EPS = 1e-8;
    char room[N][N];
    struct Point    {
        int x, y;
        Point (int x, int y) : x (x), y (y) {}
    };
    int n, m;
    bool vis[N][N];
    
    void back_nomal(int x, int y)   {
        vis[x][y] = false;
        if (x - 1 >= 1) vis[x-1][y] = false;
        if (y + 1 <= m) vis[x][y+1] = false;
    }
    
    void back_special(int x, int y, int type) {
        if (type == 1)  {
            back_nomal (x, y);  return ;
        }
        else if (type == 2)  {
            if (x + 1 <= n) {
                vis[x+1][y] = false;
            }
            if (y + 1 <= m) {
                vis[x][y+1] = false;
            }
        }
        else if (type == 3) {
            if (x + 1 <= n) {
                vis[x+1][y] = false;
            }
            if (y - 1 >= 1) {
                vis[x][y-1] = false;
            }
        }
        else if (type == 4) {
            if (x - 1 >= 1) {
                vis[x-1][y] = false;
            }
            if (y - 1 >= 1) {
                vis[x][y-1] = false;
            }
        }
        vis[x][y] = false;
    }
    
    bool light_nomal(int x, int y)  {
        if (x - 1 >= 1 && room[x-1][y] != '.')  return false;
        if (y + 1 <= m && room[x][y+1] != '.')  return false;
        if (x - 1 >= 1) {
            vis[x-1][y] = true;
        }
        if (y + 1 <= m) {
            vis[x][y+1] = true;
        }
        vis[x][y] = true;
        return true;
    }
    
    bool light_special(int x, int y, int type)    {
        if (type == 1)  {
            return light_nomal (x, y);
        }
        else if (type == 2)  {
            if (x + 1 <= n && room[x+1][y] != '.')  return false;
            if (y + 1 <= m && room[x][y+1] != '.')  return false;
            if (x + 1 <= n) {
                vis[x+1][y] = true;
            }
            if (y + 1 <= m) {
                vis[x][y+1] = true;
            }
        }
        else if (type == 3) {
            if (x + 1 <= n && room[x+1][y] != '.')  return false;
            if (y - 1 >= 1 && room[x][y-1] != '.')  return false;
            if (x + 1 <= n) {
                vis[x+1][y] = true;
            }
            if (y - 1 >= 1) {
                vis[x][y-1] = true;
            }
        }
        else if (type == 4) {
            if (x - 1 >= 1 && room[x-1][y] != '.')  return false;
            if (y - 1 >= 1 && room[x][y-1] != '.')  return false;
            if (x - 1 >= 1) {
                vis[x-1][y] = true;
            }
            if (y - 1 >= 1) {
                vis[x][y-1] = true;
            }
        }
        vis[x][y] = true;
        return true;
    }
    
    int main(void)    {
        while (scanf ("%d%d", &n, &m) == 2) {
            if (!n && !m)   break;
            for (int i=1; i<=n; ++i)    {
                scanf ("%s", room[i] + 1);
            }
            int cnt = 0;
            memset (vis, false, sizeof (vis));
            vector<Point> V;
            for (int i=1; i<=n; ++i)    {
                for (int j=1; j<=m; ++j)    {
                    if (room[i][j] == '.')  {
                        cnt++;
                        V.push_back (Point (i, j));
                    }
                }
            }
            if (cnt == 0)   {
                puts ("0"); continue;
            }
            int tot = 1 << cnt;
            int ans = INF;
            for (int i=0; i<tot; ++i) {
                for (int k=0; k<cnt; ++k)   {
                    for (int l=1; l<=4; ++l)    {
                        bool ok = true;
                        for (int j=0; j<cnt; ++j)   {
                            if (i & (1 << j))   {
                                if (j == k) {
                                    if (!light_special (V[j].x, V[j].y, l))    {
                                        ok = false; break;
                                    }
                                }
                                else    {
                                    if (!light_nomal (V[j].x, V[j].y))  {
                                        ok = false; break;
                                    }
                                }
                            }
                        }
                        if (!ok)    {
                            for (int j=0; j<cnt; ++j)   {
                                if (j == k) back_special (V[j].x, V[j].y, l);
                                else    back_nomal (V[j].x, V[j].y);
                            }
                            continue;
                        }
                        bool flag = true;
                        for (int j=0; j<cnt; ++j)   {
                            int x = V[j].x, y = V[j].y;
                            if (!vis[x][y]) {
                                flag = false;   break;
                            }
                        }
                        if (flag)   {
                            ans = min (ans, __builtin_popcount (i));
                        }
                        for (int j=0; j<cnt; ++j)   {
                            if (j == k) back_special (V[j].x, V[j].y, l);
                            else    back_nomal (V[j].x, V[j].y);
                        }
                    }
                }
            }
            printf ("%d
    ", ans == INF ? -1 : ans);
        }
    
        return 0;
    }
    

      

    编译人生,运行世界!
  • 相关阅读:
    Linux系统、版本、CPU、内存查看、硬盘空间
    Spring AOP 通过order来指定顺序
    关于 String.intern() 的思考
    java枚举类型构造方法为什么是private的
    Spring Cache 介绍
    Linux下redis的安装
    使用Spring实现读写分离( MySQL实现主从复制)
    Intellij Idea 13 快捷键(与Eclipse比对)以及基本的设置
    linux下tomcat的shutdown命令杀不死进程
    求N个元素的子集合个数
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4902677.html
Copyright © 2020-2023  润新知