这个题最多只有15个位置,每个位置放或者不放,可以通过回溯来解决。
果然我回溯很弱,虽然一开始就想到了这个算法却傻乎乎的写了个阶乘的算法,果断超时。
后来重写了以后交上去WA了。可能是代码写得比较搓,就参考cdc的代码格式又写了一个,他的思路和我的是一样的,然后就A了。
对比之后发现他的代码在回溯之后恢复状态是恢复了四周全部的,而我原来只恢复了可以照到的位置,按理来说这里应该不会有问题的。
然后我把自己的搓代码稍微化简了一下,改了一下恢复状态的地方,结果也AC了。。
下面是参考cdc的代码写的,我自己那个搓代码就不发了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define MAXN 205
using namespace std;
int n,m,N,ans;
char grid[MAXN][MAXN];
bool light[MAXN][MAXN],use;
int x[20],y[20];
bool Judge(int pos,int num)
{
int xx=x[pos],yy=y[pos];
switch(num)
{
case 1:
return ((!light[xx][yy]||!light[xx-1][yy]||!light[xx][yy+1])&&(grid[xx-1][yy]!='#'&&grid[xx][yy+1]!='#'));
case 2:
return ((!light[xx][yy]||!light[xx+1][yy]||!light[xx][yy+1])&&(grid[xx+1][yy]!='#'&&grid[xx][yy+1]!='#'));
case 3:
return ((!light[xx][yy]||!light[xx+1][yy]||!light[xx][yy-1])&&(grid[xx+1][yy]!='#'&&grid[xx][yy-1]!='#'));
case 4:
return ((!light[xx][yy]||!light[xx-1][yy]||!light[xx][yy-1])&&(grid[xx-1][yy]!='#'&&grid[xx][yy-1]!='#'));
}
}
void dfs(int pos,int res)
{
if(res>=ans) return;
if(pos==N)
{
for(int i=0; i<N; ++i)
if(!light[x[i]][y[i]]) return;
ans=min(ans,res);
}
else
{
bool note[5];
note[0]=light[x[pos]][y[pos]];
note[1]=light[x[pos]-1][y[pos]];
note[2]=light[x[pos]][y[pos]+1];
note[3]=light[x[pos]+1][y[pos]];
note[4]=light[x[pos]][y[pos]-1];
for(int i=1; i<=5; ++i)
{
if(i==1&&Judge(pos,i))
{
light[x[pos]][y[pos]]= light[x[pos]-1][y[pos]]=light[x[pos]][y[pos]+1]=true;
dfs(pos+1,res+1);
}
else if(i==5)
dfs(pos+1,res);
else if(!use)
{
if(i==2&&Judge(pos,i))
{
light[x[pos]][y[pos]]=light[x[pos]+1][y[pos]]=light[x[pos]][y[pos]+1]=true;
use=true;
dfs(pos+1,res+1);
use=false;
}
else if(i==3&&Judge(pos,i))
{
light[x[pos]][y[pos]]=light[x[pos]+1][y[pos]]=light[x[pos]][y[pos]-1]=true;
use=true;
dfs(pos+1,res+1);
use=false;
}
else if(i==4&&Judge(pos,i))
{
light[x[pos]][y[pos]]=light[x[pos]-1][y[pos]]=light[x[pos]][y[pos]-1]=true;
use=true;
dfs(pos+1,res+1);
use=false;
}
}
light[x[pos]][y[pos]]=note[0];
light[x[pos]-1][y[pos]]=note[1];
light[x[pos]][y[pos]+1]=note[2];
light[x[pos]+1][y[pos]]=note[3];
light[x[pos]][y[pos]-1]=note[4];
}
}
}
int main()
{
while(scanf("%d%d",&n,&m)&&!(!n&&!m))
{
memset(grid,'.',sizeof(grid));
memset(light,0,sizeof(light));
for(int i=1; i<=n; ++i)
scanf("%s",grid[i]+1);
N=0;
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j)
if(grid[i][j]=='.')
{
x[N]=i;
y[N]=j;
N++;
}
for(int i=0; i<=n+1; ++i)
grid[i][m+1]='.';
ans=MAXN;
use=false;
dfs(0,0);
if(ans==MAXN) printf("-1\n");
else printf("%d\n",ans);
}
return 0;
}