您的位置:首页 > 大数据 > 人工智能

HDU 4770 Lights Against Dudely 解题报告

2013-11-18 19:26 417 查看
题目

题意:

有矩阵n*m,每个单元是一个房间,有些房间可被照亮有些不能,可被照亮的房间最多15个。在(x,y) 放置灯那么 (x,y+1 )和 (x+1,y)都会被照亮,但是有一盏灯可以转动90或者180或270度。问使得所有可被照亮的房间都被照亮且不可被照亮的房间不被照亮需要的最少的灯,不可能则输出-1.

解法:

可以用状压,枚举哪个房间放灯及灯转动的角度,然后看每个可照亮的房间是否放灯。

代码:

//Time:0ms
//Memory:532KB
//Length:1903B
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 210;
char ma[MAXN][MAXN];
pair<int,int> room[MAXN];
int top=0,ans,bel[MAXN][MAXN];
bool vi[20],tvi[20][20];
int to[4][3][2]={{{0,0},{-1,0},{0,1}},{{0,0},{0,1},{1,0}},{{0,0},{1,0},{0,-1}},{{0,0},{-1,0},{0,-1}}};
inline int cha(int x,int y,int d)
{
int tx,ty,cnt=0,whi;
for(int i=0;i<3;++i)
{
tx=x+to[d][i][0],ty=y+to[d][i][1];
if(ma[tx][ty]=='#') cnt=-MAXN;
if(ma[tx][ty]=='.') whi=bel[tx][ty];
else continue;
cnt+=!vi[whi];
vi[whi]=1;
}
return cnt;
}
void check(int cant,int h,int now,int cnt)
{
int tmp;
if(cnt==top)
{
ans=min(ans,now);
return ;
}
memcpy(tvi[h],vi,sizeof(vi));
for(int i=h;i<top&&now<ans;++i)
if(i!=cant)
{
memcpy(vi,tvi[h],sizeof(vi));
tmp=cha(room[i].first,room[i].second,0);
if(tmp<0) continue;
check(cant,i+1,now+1,cnt+tmp);
}
return ;
}
int main()
{
//freopen("/home/moor/Code/output","r",stdin);
int n,m;
while(scanf("%d%d",&n,&m)==2&&n&&m)
{
memset(ma,0,sizeof(ma));
memset(bel,-1,sizeof(bel));
for(int i=1;i<=n;++i)
scanf("%s",&ma[i][1]);
top=0;
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
if(ma[i][j]=='.')
bel[i][j]=top,room[top++]=make_pair(i,j);
ans=MAXN;
for(int i=0;i<top;++i)
{
for(int j=0;j<4;++j)
{
memset(vi,0,sizeof(vi));
int tmp=cha(room[i].first,room[i].second,j);
if(tmp<0) continue;
check(i,0,1,tmp);
}
//printf("%d\n",ans);
}
if(top==0) ans=0;
printf("%d\n",ans<MAXN?ans:-1);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: