您的位置:首页 > 其它

POJ 2965 DFS解法 原理与1753类似 稍加改造即可ac

2017-05-01 18:02 351 查看
//在poj1753 基础上改造一下,  ac用时大概 300~500 ms   不会超时

//思路非常简单,先dfs求出最小次数,再次dfs记录下 达到最小次数的 路径即可

#include<iostream>

using namespace std;

#include<cstdio> 

#include<cstring>

bool arr[4][4]={false}; // + closed用0表示关  - open用1表示开 

int ans = 999999;    //其实只要初始化为17 就行,最多转16次 , 

bool flag;

int a[20],b[20]; // 两个数组用来记录下标,当然你也可以有struct pos{ int x,int y} array[20]; 

void flip(int x,int y)

{
int i,j;
for(i=0;i<4;i++)
{
arr[i][y] = !arr[i][y]; // 翻所在列 
}
for(j=0;j<4;j++)
{
if(j!=y)
{
arr[x][j] = !arr[x][j]; // 翻所在行 
}
}

}

bool judge() //判断是否全开,即全部为 -  即是否为true 

{
int i,j;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
if(arr[i][j] != true)
return false;
return true;

}

void dfs(int x,int y,int deep){  //dfs深度搜索 
if(judge()){
if(deep < ans)
ans = deep;   //ans 保存最小翻转次 
return ;

}
if(x<0 || x>3 || y<0 || y>3)
return ;
int nx,ny;

nx=(x+1)%4;    
ny=y+(x+1)/4;

flip(x,y);

dfs(nx,ny,deep+1);
flip(x,y);

dfs(nx,ny,deep);

}

void Dfs(int x,int y,int deep){  //dfs深度搜索 
if(judge()){
if(deep == ans)
flag=true;   //已达到最小翻转次数 
return ;

}
if(flag || x<0 || x>3 || y<0 || y>3)  //多了一个条件满足flag即可退出 
return ;
int nx,ny;

nx=(x+1)%4;   // 注意此处按列搜索,也可稍加改造按列搜索   结果可能与答案不一样,只要找出一条翻转路径即可 
ny=y+(x+1)/4;

/*
y = (y+1)%4;  
//相当于按行遍历  这种写法 测试样例与答案一样 

    nx = x + (y+1)/4;
*/
flip(x,y);

Dfs(nx,ny,deep+1);
a[deep]=x; //记录下标x   
b[deep]=y; //记录下标y 
flip(x,y);

Dfs(nx,ny,deep);

}

int main(){
char str[5];
int i,j;
for(i=0;i<4;i++)
{
cin >> str;
for(j=0;j<4;j++)
if(str[j] == '-')
arr[i][j] = true;
}
dfs(0,0,0); // 先计算出 最小翻转次数 
flag=false;
Dfs(0,0,0); //再次Dfs 稍作修该 保存路径 , 当 达到 dfs求出最小次数ans 即可将flag 表为true 

  cout << ans << endl;

  for(i=0;i<ans;i++){

  cout << a[i]+1 <<" " << b[i]+1 << endl;  
//注意 he state of a handle in any location [i, j] (1 ≤ i, j ≤ 4)
//行列都是从1开始  ,我开的数组是 从(0,0) ~ (3,3) 
}
return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj 2965 dfs解法