[POJ]POJ2965(dfs)

题意:给出一个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; make(x,y); f=dfs(s-1,x+1,1); if(f)ans[s]=x*10+y; make(x,y); return f; } } int main(){ rep(i,4)scanf("%s",a[i]+1); for(int i=0;i<=16;i++){ if(dfs(i,1,1)){ cout<<i<<endl; for(int j=i;j>=1;j--){ cout<<ans[j]/10<<" "<<ans[j]%10<<endl; } return 0; } } return 0; }

猜你喜欢

转载自www.cnblogs.com/xutianshu/p/10157415.html