这个题最多只有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; }