Flip Game POJ-1753 (位运算&DFS)
思路:每个位置至多翻转一次,一开始我以为在位置 A A A翻一次,然后进行其他影响 A A A的操作,再翻转 A A A的操作是对 A A A的贡献有影响的,但是仔细想想,只要翻转 A A A的相邻位置, A A A也会进行相应翻转,所以 A A A翻转两次最后等于没翻转。
所以可以考虑暴力
2
16
2^{16}
216位运算。
或者贪心步数从小到
d
f
s
dfs
dfs。
位运算:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
#define il inline
int a[5][5],d[4][2]={0,1,0,-1,1,0,-1,0};
char c;
void fun(int x,int y){
a[x][y]^=1;
for(int i=0;i<4;i++){
int nx=x+d[i][0],ny=y+d[i][1];
if(nx>=0&&nx<4&&ny>=0&&ny<4) a[nx][ny]^=1;
}
}
bool check(){
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
if(a[i][j]!=a[0][0]) return 0;
return 1;
}
int main(){
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
cin>>c,a[i][j]=c=='b'?1:0;
int ans=inf;
for(int i=0;i<(1<<16);i++){
int s=0;
for(int j=0;j<16;j++){
if((i>>j)&1){
s++;
int x=j/4,y=j%4;
fun(x,y);
}
}
if(check()) ans=min(ans,s);
for(int j=0;j<16;j++)
if((i>>j)&1){
int x=j/4,y=j%4;
fun(x,y);
}
}
printf(ans==inf?"Impossible":"%d\n",ans);
return 0;
}
d f s dfs dfs:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
#define il inline
int a[5][5],d[4][2]={0,1,0,-1,1,0,-1,0};
char c;
void fun(int x,int y){
a[x][y]^=1;
for(int i=0;i<4;i++){
int nx=x+d[i][0],ny=y+d[i][1];
if(nx>=0&&nx<4&&ny>=0&&ny<4) a[nx][ny]^=1;
}
}
bool check(){
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
if(a[i][j]!=a[0][0]) return 0;
return 1;
}
int tot,ok;
void dfs(int x,int y,int s){
if(ok) return;
if(s==tot||x==4){
if(check()) ok=1;
return;
}
fun(x,y);
if(y+1<4) dfs(x,y+1,s+1);
else dfs(x+1,0,s+1);
fun(x,y);
if(y+1<4) dfs(x,y+1,s);
else dfs(x+1,0,s);
}
int main(){
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
scanf("\n%c",&c),a[i][j]=c=='b'?1:0;
int ans=inf;
for(;tot<=16;tot++){
dfs(0,0,0);
if(ok){
printf("%d\n",tot);
return 0;
}
}
printf("Impossible\n");
return 0;
}