标签: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