您的位置:首页 > 其它

POJ2488 -- POJ1154-- DFS

2015-06-04 19:10 381 查看
 一。POJ2488该题用到了很基础的DFS。

 

1. 理解清楚题意,什么叫字典序。

图中红色数字1/2/3....7/8是马可以行走到的位置,按照字典序行走,也就是按12345678的顺序依次行走。



 

2.在该题的DFS算法中,可以尝试八种走法,如果其中一条路不通,则需要尝试其他的路径。因此可以用for循环8次,或者8个if语句。

在这里设立了一个标志位flag,如果完成了,则置1,否则说明是impossible的路径。

chess[x][y]=1;表示该点已经行走过了,如果需要回退时,记得将chess[x][y]=0;

需要注意的是下面的 if 判断:如果完成了,是不需要回退的。

if(flag==0){  //如果没有完成,才需要回退
count--;
chess[x][y]=0;

}

 

3.最后附上全部代码

#include <stdio.h>
#include <stdlib.h>
#define MAX 26
int row,col;
int flag,count;
int chess[MAX][MAX];
char output[27][2];

void DFS(int x, int y){
count++;
chess[x][y]=1;
if(count == row*col){
flag =1;
return;
}

if(x >1 && y>0 && chess[x-2][y-1]==0){//按字典序,依次走下面的八个点
output[count][0]='A'+x-2;
output[count][1]='1'+y-1;
DFS(x-2,y-1);
}
if(x >1 && y<(col-1) && chess[x-2][y+1]==0){
output[count][0]='A'+x-2;
output[count][1]='1'+y+1;
DFS(x-2,y+1);
}
if(x >0 && y>1 && chess[x-1][y-2]==0){
output[count][0]='A'+x-1;
output[count][1]='1'+y-2;
DFS(x-1,y-2);
}
if(x >0 && y<(col-2) && chess[x-1][y+2]==0){
output[count][0]='A'+x-1;
output[count][1]='1'+y+2;
DFS(x-1,y+2);
}
if(x<(row-1) && y>1  && chess[x+1][y-2]==0){
output[count][0]='A'+x+1;
output[count][1]='1'+y-2;
DFS(x+1,y-2);
}
if(x<(row-1) && y<(col-2)&& chess[x+1][y+2]==0){
output[count][0]='A'+x+1;
output[count][1]='1'+y+2;
DFS(x+1,y+2);
}
if(x <(row-2) && y>0 && chess[x+2][y-1]==0){
output[count][0]='A'+x+2;
output[count][1]='1'+y-1;
DFS(x+2,y-1);
}
if(x <(row-2) && y<(col-1) && chess[x+2][y+1]==0){
output[count][0]='A'+x+2;
output[count][1]='1'+y+1;
DFS(x+2,y+1);
}
if(flag==0){  //如果没有完成,才需要回退
count--;
chess[x][y]=0;

}

}

int main()
{
int n;
//freopen("input.txt","r",stdin);
scanf("%d",&n);
int i=0;
for(i=0;i<n;i++){
memset(chess,0,sizeof(chess));
memset(output,0,sizeof(output));
scanf("%d%d",&col,&row);
flag = 0;
count = 0;
output[count][0]='A';
output[count][1]='1';
DFS(0,0);
printf("Scenario #%d:\n",i+1);
if(flag == 0){
printf("impossible\n");
}else{
printf("%s\n",output);
}
printf("\n");

}
return 0;
}


 二。POJ1154的dfs。

其实上一题的dfs还可以更简化的表达出来。下面我把简单的表达在这里写出来。

类似于常见的迷宫题,只能走上下左右。

我们通过dx和dy来表达只能走上下左右,eg向上走:X+dx[0]  /  Y+dy[0]。

int dx[4]={0,0,-1,1};

int dy[4]={-1,1,0,0};

然后通过一个变量x_temp和y_temp来表达接下来要走的路径,首先判断是否越界。然后再判断是否被访问过。

上一题是每一个尝试都通过if进行判断,而在这里通过一个for循环,全部一起判断了。

如果符合条件 -->走下一不。 不符合条件,即上下左右都不能走的时候,记得将访问标志清0.

 

#include <stdio.h>
#include <stdlib.h>
int row , col;
int map[25][25];
int visit[30];
int maxNumb;
int dx[4]={0,0,-1,1};
int dy[4]={-1,1,0,0};

void dfs(int step,int x, int y){
if( maxNumb<step){
maxNumb = step;
}
visit[map[y][x]]=1;
int i=0;
int x_temp,y_temp;

for(i=0;i<4;i++){  //上下左右
x_temp= x+dx[i];
y_temp=y+dy[i];
if(x_temp>=0 && x_temp<col && y_temp>=0 && y_temp<row && visit[map[y_temp][x_temp]]==0 ){  //先判断是否越界,再判断数组是否访问过

dfs(step+1,x_temp,y_temp);
}
}

visit[map[y][x]]=0;//上下左右都不能走,需要清空标志位

}
int main()
{
memset(map,0,sizeof(map));
memset(visit,0,sizeof(visit));
freopen("input.txt","r",stdin);
scanf("%d%d",&row,&col);
int i,j;
maxNumb=0;
for(i=0;i<row;i++){
for(j=0;j<col;j++){
char c;
scanf("%c",&c);
while(c<'A' || c>'Z'){
scanf("%c",&c);
}
map[i][j]=c-'A';
}
}
dfs(1,0,0); //从坐标点0 0 出发

printf("%d\n",maxNumb);
return 0;
}


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