链接:http://poj.org/problem?id=2965
题意:有4*4的矩阵,想要将每个开关的状态变成-,每一次操作定义为:选中一个以及该行该列的所有开关都取反一次,求最少的操作次数,并输出其路径
分析:题目是poj1753的变式,首先必须明确的是操作的顺序对结果是没有影响的,只有4*4的矩阵,暴力dfs一遍2^16的状态数是可以的。dfs深搜要最小路径的话要保存一下临时路径,在不断比较的过程中赋值,最后输出答案。我就是比较菜得将比较得答案初始化为0,然后就一直找不出哪里错了。。然后对于这个矩阵坐标的话应该是从0开始的下标比较方便,这样就很容易得出s=i*4+j+1,i=s/4,j=s%4;
代码:
#include<cstdio>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
char g[5][5];
int a[5][5];
int ansx[20],ansy[20];
int tempx[20],tempy[20];
int res;
int judge(void){
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if(!a[i][j])return 0;
}
}
return 1;
}
void flip(int s){
int r=s/4;
int c=s%4;
for(int i=0;i<4;i++){
a[r][i]=!a[r][i];
a[i][c]=!a[i][c];
}
a[r][c]=!a[r][c];
}
void solve(int s,int t){//遍历到s个,翻转了t个
if(judge()){
if(t<res){
res=t;
for(int i=1;i<=res;i++){
ansx[i]=tempx[i];
ansy[i]=tempy[i];
}
}
return ;
}
if(s>=16)return ;
solve(s+1,t);
flip(s);
tempx[t+1]=s/4+1;
tempy[t+1]=s%4+1;
solve(s+1,t+1);
flip(s);
return ;
}
int main(){
res=inf;
for(int i=0;i<4;i++){
gets(g[i]);
for(int j=0;j<4;j++){
a[i][j]=(g[i][j]=='-'?1:0);
}
}
solve(0,0);
printf("%d\n",res);
for(int i=1;i<=res;i++){
printf("%d %d\n",ansx[i],ansy[i]);
}
}