标签:des style class blog code http
2 2 ## ## 2 3 #.. ..# 3 3 ### #.# ### 0 0
0 2 -1
方法:一开始的思路 是要使用搜索来解决的,但是写到一半写不下去了。然后 看了大神的思路,觉得很好,就按照他的思路写了 一下。具体思路就是 因为脆弱的房间的个数不超过15,那么我们可以直接就二进制暴力枚举就可以了。最多的策略数就是2^15个,然后就是需要旋转的房间单独处理就可以了,这样的复杂度是可以接受的。
代码:
#include <iostream> #include <cstdio> #include <cstring> #define INF 1000 using namespace std; char ma[202][202]; int vis[20]; struct node //用来记录每个脆弱的房间的坐标 { int x,y; } nd[20]; struct dir //记录可以旋转的灯可以照亮的房间的坐标方向 { int x[3]; int y[3]; } d[4]; void init() //四个旋转的方向的初始化 { d[0].x[0]=0; d[0].y[0]=0; d[0].x[1]=-1; d[0].y[1]=0; d[0].x[2]=0; d[0].y[2]=1; d[1].x[0]=0; d[1].y[0]=0; d[1].x[1]=-1; d[1].y[1]=0; d[1].x[2]=0; d[1].y[2]=-1; d[2].x[0]=0; d[2].y[0]=0; d[2].x[1]=0; d[2].y[1]=-1; d[2].x[2]=1; d[2].y[2]=0; d[3].x[0]=0; d[3].y[0]=0; d[3].x[1]=1; d[3].y[1]=0; d[3].x[2]=0; d[3].y[2]=1; } int main() { int n,m,k; init(); while(cin>>n>>m) { if(n==0&&m==0) break; k=0; //k用来记录所有的脆弱的房间的个数 for(int i=1; i<=n; i++) { scanf("%s",&ma[i][1]); for(int j=1; j<=m; j++) if(ma[i][j]=='.') { ma[i][j]=k; //直接把地图的点标记成记录的第K个点,后续处理会简单许多 nd[k].x=i; nd[k++].y=j; } } if(k==0) { printf("0\n"); continue; } int x,y,ans=INF,tx,ty; int num=(1<<k); bool flag=true; for(int i=1; i<num; i++) //二进制枚举 { for(int j=0; j<k; j++) //枚举第j位可旋转 if(i&(1<<j)) { memset(vis,0,sizeof(vis)); flag=true; for(int mm=0; mm<k&&flag; mm++) //枚举其他位的情况 if(i&(1<<mm)&&j!=mm) { x=nd[mm].x; y=nd[mm].y; vis[ma[x][y]]=1; if(x>=2) { if(ma[x-1][y]!='#') vis[ma[x-1][y]]=1; else flag=false; } if(y+1<=m) { if(ma[x][y+1]!='#') vis[ma[x][y+1]]=1; else flag=false; } } if(!flag) continue; for(int nn=0; nn<=3; nn++) //枚举可旋转房间的四个方向 { flag=true; tx=-1; ty=-1; x=nd[j].x+d[nn].x[1]; y=nd[j].y+d[nn].y[1]; if(x>=1&&x<=n&&y>=1&&y<=m) { if(ma[x][y]!='#') tx=ma[x][y]; //因为四个方向总要改变vis比较麻烦,所以单独处理旋转的房间覆盖的房间 else flag=false; } x=nd[j].x+d[nn].x[2]; y=nd[j].y+d[nn].y[2]; if(x>=1&&x<=n&&y>=1&&y<=m) { if(ma[x][y]!='#') ty=ma[x][y]; //同上 else flag=false; } vis[j]=1; //别忘了这一步 if(flag) { int sum=0; for(int v=0; v<k; v++) if(!vis[v]&&tx!=v&&ty!=v) //枚举所有的房间,看是否的房间都已经被覆盖 { flag=false; break; } if(flag) { for(int v=0; v<k; v++) if(i&(1<<v)) sum++; if(ans>sum) ans=sum; } } } } } if(ans<INF) cout<<ans<<endl; else cout<<-1<<endl; } return 0; }
hdu 4770 Lights Against Dudely,布布扣,bubuko.com
hdu 4770 Lights Against Dudely
标签:des style class blog code http
原文地址:http://blog.csdn.net/knight_kaka/article/details/28424761