由题中最多只有15个需要点亮的灯可知,暴力法可行。。。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=205, maxr=20 ,INF=(int)1e9 ,EPS = 100;
char mp[maxn][maxn];
int N,M;
int light[maxr] , d[maxr] ;
int dx[4][2] = {{-1,0}, {0,1}, {1,0}, {0,-1}};
int dy[4][2] = {{0,1} , {1,0}, {0,-1}, {-1,0}};
struct ROOM{
int x[maxr],y[maxr];
int RN;
void Init() { RN = 0 ;}
void add_room(int a,int b) {
x[RN] = a , y[RN] = b , RN++;
}
int room_num(int a,int b){
for(int i=0;i<RN;i++)
if(x[i]==a && y[i]==b) return i;
return -1;
}
}R;
int bitcount(int x){
int cnt=0;
while(x) cnt+=x&1 , x>>=1;
return cnt;
}
bool InMap(int x,int y){
return x>=0 && x<N && y>=0 && y<=M ;
}
bool Dangrous(int t){
for(int i=0 ; i<2 ; i++){
int x = R.x[t] + dx[d[t]][i] , y = R.y[t] + dy[d[t]][i];
if(!InMap(x,y)) continue;
if(mp[x][y] == '#') return true;
}
return false;
}
bool AllLighted(){
for(int t=0 ; t<R.RN ; t++){
if(light[t]==0) return false;
if(light[t]>=EPS && Dangrous(t)) return false;
}
return true;
}
void TurnOn(int u){
for(int i=0; i<2; i++){
int x = R.x[u] + dx[d[u]][i] , y = R.y[u] + dy[d[u]][i];
int tmp = R.room_num(x,y);
if(tmp != -1) light[tmp]++;
}
}
void TurnOff(int u){
for(int i=0; i<2; i++){
int x = R.x[u] + dx[d[u]][i] , y = R.y[u] + dy[d[u]][i];
int tmp = R.room_num(x,y);
if(tmp != -1) light[tmp]--;
}
}
bool check(int S){
memset(d,0,sizeof(d));
memset(light,0,sizeof(light));
for(int t=0; t<R.RN; t++) if(S&(1<<t)) {
light[t] += 100;
TurnOn(t);
}
if(AllLighted()) return true;
for(int t=0; t<R.RN; t++) if(S&(1<<t)) {
for(int i=0; i<4; i++){
TurnOff(t) , d[t] = i ,TurnOn(t);
if(AllLighted()) return true;
TurnOff(t) , d[t]=0 , TurnOn(t);
}
}
return false;
}
int main()
{
while(scanf("%d%d",&N,&M)!=EOF && N+M){
R.Init();
for(int i=0 ; i<N; i++){
scanf("%s",mp[i]);
for(int j=0; j<M; j++) if(mp[i][j]=='.') {
R.add_room(i,j) ;
}
}
int ans= INF;
if(R.RN==0) {puts("0"); continue; }
int tt;
for(int S=0 ; S<(1<<R.RN) ; S++){
if((tt=bitcount(S)) >= ans || !check(S)) continue;
ans = tt;
}
if(ans>=INF) ans=-1;
printf("%d\n",ans);
}
return 0;
}