您的位置:首页 > 其它

Light OJ 1092 Lighted Panels (状压)

2016-03-25 11:52 483 查看
解析:可以参考POJ 3279。不同的是这里要把最上面一行和最左一行一起状压。

:

[code]#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;
const int INF = 0x3f3f3f3f;

char mp[10][10];
int n,m,state[10][10],flip[10][10];

void init(){
int i,j;
for(i = 0;i < n;i++){
for(j = 0;j < m;j++){
state[i][j] = (mp[i][j]=='.');
flip[i][j] = 0;
}
}
}

void change(int x,int y){
int i,j,xx,yy;
for(i = -1;i <= 1;i++){
for(j = -1;j <= 1;j++){
xx = x+i,yy = y+j;
if(xx>=n||xx<0||yy>=m||yy<0) continue;
flip[xx][yy] ^= 1;
}
}
}

int calc(){
int i,j,res = 0;
for(i = 1;i < n;i++){
for(j = 1;j < m;j++){
if(state[i-1][j-1]^flip[i-1][j-1]){
change(i,j);
res++;
}
}
}
for(j = 0;j < m;j++){
if(state[n-1][j]^flip[n-1][j]) return INF;
}
for(i = 0;i < n;i++){
if(state[i][m-1]^flip[i][m-1]) return INF;
}
return res;
}

void sol(){
int i,j,S,Ed = 1<<(n+m-1),ans = INF,tmp;
for(S = 0;S < Ed;S++){
memset(flip,0,sizeof(flip));
tmp = 0;
for(i = 0;i < n+m-1;i++){
if(!(S>>i&1)) continue;
tmp++;
if(i >= m) change(i-m+1,0);
else change(0,i);
}
ans = min(ans,tmp+calc());
}
if(ans == INF) puts("impossible");
else printf("%d\n",ans);
}

int main(){
int i,j,cas;
scanf("%d",&cas);
for(int T=1;T<=cas;T++){
scanf("%d%d",&n,&m);
for(i = 0;i < n;i++){
scanf("%s",mp[i]);
}
init();
printf("Case %d: ",T);
sol();
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: