hdu 4770 Lights Against Dudely(二进制枚举情况)

来源:互联网 发布:java聊天室传文件 编辑:程序博客网 时间:2024/06/05 02:38

题意:N*M的地图,需要照亮所有的'.'(最多15个),但是'#'不能被照亮,问最多需要多少灯。每盏灯能照亮当前格子,右边格子和上方格子。有一盏特别的灯,能够转向。

http://acm.hdu.edu.cn/showproblem.php?pid=4770

#include <stdio.h>  #include <queue>  #include <memory.h>  #include <iostream>  using namespace std;  #define INF 1000000000  char x[210][210];  int cnt;  bool vis[16];  struct node{int a,b;}y[210];int dx[8]={-1,0,0,1,1,0,0,-1};int dy[8]={0,1,1,0,0,-1,-1,0};int n,m;    bool judge(int a,int b,int k){      memset(vis,0,sizeof(vis));      int w=1;      int aa=a;      while(a>0){          if(a%2==1){              if(w!=b){  //下标为w的灯是普通灯             vis[w]=1;            for(int i=0;i<2;++i){            int g=x[y[w].a+dx[i]][y[w].b+dy[i]]; //这个位置是#还是下标if(g=='#')return 0;                 vis[g]=1;            }            }else{  vis[w]=1;                for(int i=k*2;i<=k*2+1;++i){            int g=x[y[w].a+dx[i]][y[w].b+dy[i]]; //这个位置是#还是下标if(g=='#')return 0; vis[g]=1;                }            }          }          w++;          a/=2;    }          for(int i=1;i<=cnt;i++)if(!vis[i])return 0;      return 1;  }    int main(){      while(~scanf("%d%d",&n,&m)){          if(n==0&&m==0)break;          memset(x,0,sizeof(x));          cnt=0;          for(int i=1;i<=n;i++){              scanf("%s",x[i]+1);              for(int j=1;j<=m;j++){                  if(x[i][j]=='.'){                      x[i][j]=++cnt;                          y[cnt].a=i;y[cnt].b=j;                }              }          }          if(!cnt){              printf("0\n");              continue;          }          int end=(1<<cnt);                    int ans=INF;          for(int i=1;i<end;i++){ //二进制枚举灯的状态             for(int j=0;j<=cnt;j++){  //挑出要把哪一个作为特殊灯或不选(取0)         int tmp=i;                  int ss=0;                  while(tmp){                      if(tmp%2==1)ss++;  //求出这种状态要点几盏灯                     tmp/=2;                  }                  for(int k=1;k<=3;k++){  //枚举这盏特殊灯的方向                     if(judge(i,j,k)){ ans=min(ans,ss);  //这种状态符合条件,更新最少灯数 break;}                }              }          }          if(ans!=INF)              printf("%d\n",ans);          else              printf("-1\n");      }      return 0;  } 


0 0