POJ2488 -- POJ1154-- DFS

 一。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;

    }
扫描二维码关注公众号,回复: 2201182 查看本文章

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;
}


 

猜你喜欢

转载自blog.csdn.net/genius9_9/article/details/46365891