7_11_A题 Lights Against Dudely [HDU 4770] (状态压缩+暴力)

来源:互联网 发布:linux查看db2数据库 编辑:程序博客网 时间:2024/05/29 08:22

7_11_A题 Lights Against Dudely [HDU 4770] (状态压缩+暴力)


简单题意

给出一个矩形,可以在矩形的格子中放置灯,灯可以照射他所在格和下面一格,左边一格,在所有的灯中,有一个灯可以旋转,问能否把所有空格子照亮且不照射到有妖精的格子。

思路

因为空格子最多有15个,所以可以状压一下,用一个数的二进制各位来表示对应的空格子中是否放灯,然后枚举一下要旋转的灯的位置就行了。复杂度是O(215154) ,可以接受。

代码

#include <bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 205;char mat[maxn][maxn];int loc[20][2];int idx[maxn][maxn];bool fs[maxn];int n,m;int cnt = 0;int ans = 1e9+7;inline bool cheak(int x ,int y){    bool res = true;    if(x > 0 && x <= n && y > 0 && y <= m){        if(mat[x][y] == '#') res = false;        else fs[idx[x][y]] = 1;    }    return res;}int main(){    while(~scanf("%d %d", &n,&m) &&n&&m){        for(int i = 1 ; i <= n ; i ++)            scanf("%s",mat[i]+1);        cnt = 0;        memset(idx,0,sizeof idx);        for(int i = 1 ; i <= n ; i ++){            for(int k = 1 ; k <= m ; k ++){                if(mat[i][k] == '.'){                    loc[cnt][0] = i;                    loc[cnt][1] = k;                    idx[i][k] = cnt ++;                }            }        }        if(!cnt) {puts("0");continue;}        ans = 1e9+10;        for(int t = 0; t <= (1 << cnt) ; t ++){            for(int k = 0 ; k < cnt ; k ++){                if(t & (1 << k)){                    for(int f = 0 ; f < 4 ; f ++){                        bool flag = 1;                        for(int i = 0 ; i < cnt ; i ++)                            fs[i] = false;                        int x = loc[k][0];                        int y = loc[k][1];                        fs[idx[x][y]] = true;                        switch(f){                        case 0:                            flag = cheak(x-1,y);                            if(flag) flag = cheak(x,y+1);                            break;                        case 1:                            flag = cheak(x+1,y);                            if(flag) flag = cheak(x,y+1);                            break;                        case 2:                            flag = cheak(x+1,y);                            if(flag) flag = cheak(x,y-1);                            break;                        case 3:                            flag = cheak(x-1,y);                            if(flag) flag = cheak(x,y-1);                            break;                        }                        if(!flag) continue;                        for(int i = 0 ; i < cnt ; i ++){                            if(t & (1<< i) && i!=k){                                int x = loc[i][0];                                int y = loc[i][1];                                fs[idx[x][y]] = true;                                flag = cheak(x-1,y);                                if(flag) flag = cheak(x,y+1);                                if(!flag) break;                            }                        }                        if(!flag) break;                        for(int i = 0 ; i < cnt ; i ++)                            if(!fs[i]) flag = false;                        if(!flag) continue;                        int an = 0;                        for(int i = 0 ; i < cnt ; i ++)                            if(t & (1 << i))                                an ++;                        ans = min(ans,an);                    }                }            }        }        if(ans == 1e9+10) ans = -1;        printf("%d\n",ans);    }    return 0;}
0 0
原创粉丝点击