POJ3279 Fliptile(暴力)

有一种暴力是这样的,枚举一边,确定另一边。

这一题是这么解的,枚举第一行所有翻转情况,然后剩下几行其实是确定的,因为前i行翻转方式确定后只能通过第i+1行的翻转来改变第i行的状态,于是依次模拟求出剩下几行的翻转情况。

另外其实每个点最多只会被翻转一次,因为如果翻转两次和不翻转是一样的。

这题很有意思。

 #include<cstdio>
#include<cstring>
using namespace std; int n,m,sta[][],op[][]; void flip(int x,int y){
int dx[]={,,,-};
int dy[]={,-,,}; sta[x][y]^=;
for(int i=; i<; ++i){
int nx=x+dx[i],ny=y+dy[i];
if(nx< || nx>=n || ny< || ny>=m) continue;
sta[nx][ny]^=;
}
}
bool isOK(){
for(int i=; i<n; ++i){
for(int j=; j<m; ++j) if(sta[i][j]) return ;
}
return ;
}
int doit(){
int cnt=;
for(int i=; i<n-; ++i){
for(int j=; j<m; ++j){
if(sta[i][j]){
flip(i+,j);
op[i+][j]=;
++cnt;
}
}
}
if(isOK()) return cnt;
else return ;
}
int main(){
int init[][],ans[][];
scanf("%d%d",&n,&m);
for(int i=; i<n; ++i){
for(int j=; j<m; ++j) scanf("%d",&init[i][j]);
}
int res=;
for(int i=; i<(<<m); ++i){
memcpy(sta,init,sizeof(init));
memset(op,,sizeof(op));
int cnt=;
for(int j=; j<m; ++j){
if((i>>j)&){
flip(,m-j-);
op[][m-j-]=;
++cnt;
}
}
cnt+=doit();
if(res>cnt){
res=cnt;
memcpy(ans,op,sizeof(op));
}
}
if(res==) puts("IMPOSSIBLE");
else{
for(int i=; i<n; ++i){
for(int j=; j<m; ++j){
printf("%d ",ans[i][j]);
}
putchar('\n');
}
}
return ;
}
上一篇:c++实现委托


下一篇:C# activex开发中 axwebbrowser控件及 IE浏览器设置