题意:给出一个4*4的01方阵,每次可选择i,j使第i行和第j列状态取反,求全变成0的最小步数。
显然每个坐标最多选择一次,因此最多有2^16种选法,枚举最小步数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 ans[20];
int check(){
rep(i,4)
rep(j,4)if(a[i][j]=='+')return 0;
return 1;
}
void make(int x,int y){
rep(i,4)a[x][i]=(a[x][i]=='+'? '-':'+');
rep(i,4)a[i][y]=(a[i][y]=='+'? '-':'+');
a[x][y]=(a[x][y]=='+'? '-':'+');
}
int dfs(int s,int x,int y){
if(!s||x>4)return check();
if(4*(4-x)+5-y<s)return 0;
int f;
if(y<4){
f=dfs(s,x,y+1);
if(f)return 1;
make(x,y);
f=dfs(s-1,x,y+1);
if(f)ans[s]=x*10+y;
make(x,y);
return f;
}
else {
f=dfs(s,x+1,1);
if(f)return 1