题意:给出一个4*4的01方阵,每次可以选择一个坐标,使这个坐标以及相邻坐标(如果存在)状态取反,求最少步数使得全0或全1
显然每个坐标最多选一次,枚举最小步数dfs。
#include <cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long int LL;
#define st first
#define nd second
#define pb push_back
#define mp make_pair
#define pll pair <LL, LL>
#define pii pair <int, int>
#define rep(i,x) for(int i=1;i<=x;i++)
const int N = 1e5+7;
const int MX = 1e9+7;
const LL INF = 1e18+9LL;
char a[6][6];
int check(){
int x=0;
rep(i,4)
rep(j,4)if(a[i][j]=='b')x++;
return x==16||x==0;
}
void make(int x,int y){
a[x][y]=(a[x][y]=='b'? 'w':'b');
a[x][y+1]=(a[x][y+1]=='b'? 'w':'b');
a[x][y-1]=(a[x][y-1]=='b'? 'w':'b');
a[x+1][y]=(a[x+1][y]=='b'? 'w':'b');
a[x-1][y]=(a[x-1][y]=='b'? 'w':'b');
}
int dfs(int s,int x,int y){
if(!s||x>4)return check();
if(4*(4-x)+5-y<s)return 0;//剪枝后速度快4倍
int f;
if(y<4){
f=dfs(s,x,y+1);
if(f)return 1;
make(x,y);
f=f||dfs(s-1,x,y+1);
make(x,y);
return f;