DFS深度搜索-走迷宫,取数字问题

来源:互联网 发布:unctad统计数据库 编辑:程序博客网 时间:2024/05/21 17:05


取数字问题

Time Limit: 1000MS Memory limit: 65536K

题目描述

给定M×N的矩阵,其中的每个元素都是-10到10之间的整数。你的任务是从左上角(1,1)走到右下角(M,N),每一步只能够向右或者向下,并且不能够走出矩阵的范围。你所经过的方格里面的数字都必须被选取,请找出一条最合适的道路,使得在路上被选取的数字之和是尽可能小的正整数。

输入

输入第1行是两个整数M和N,(2<=M<=10,2<=N<=10),分别表示矩阵的行和列的数目。接下来M行,每行包括N个整数,就是矩阵中的每一行的N个元素。

输出

输出只有一行,就是一个整数,表示所选道路上数字之和所能达到的最小正整数。如果不能达到任何正整数,输出-1。

示例输入

2 20 21 0

示例输出

1

 

解析:因为只能往下或者右走所以在DFS时就只有两条路径,且不能往回走,就不用标记路径,一路深搜下去。

#include<stdio.h>

#include<string.h>

#include<stdlib.h>

int m,n,p,f,a[15][15];

int  dfs(int i,int j,int ans)

{

    if(i==m&&j==n)

    {

        ans+=a[i][j];

        if(ans>0&&ans<p)

        {

            f++;p=ans;

        }

        return;

    }

    if(i<m)

    {

        dfs(i+1,j,ans+a[i][j]);

    }

    if(j<n)

    {

        dfs(i,j+1,ans+a[i][j]);

    }

}

int main()

{

    int i,j;

    scanf("%d%d",&m,&n);

    p=2147483647;f=0;  //P初值设置最大,找路径和大于0且最小;

    for(i=1;i<=m;i++)

    for(j=1;j<=n;j++)

    scanf("%d",&a[i][j]);

    dfs(1,1,0);

    if(f>0)

    printf("%d",p);

    else

    printf("%d",-1);

}

 

走迷宫

Time Limit: 1000MS Memory limit: 65536K

题目描述

有一个m*n格的迷宫(表示有m行、n列),其中有可走的也有不可走的,如果用1表示可以走,0表示不可以走,输入这m*n个数据和起始点、结束点(起始点和结束点都是用两个数据来描述的,分别表示这个点的行号和列号)。现在要你编程找出所有可行的道路,要求所走的路中没有重复的点,走时只能是上下左右四个方向。如果一条路都不可行,则输出相应信息(用-1表示无路)。

输入

第一行是两个数m,n(1< m, n< 15),接下来是m行n列由1和0组成的数据,最后两行是起始点和结束点。

输出

所有可行的路径,输出时按照左上右下的顺序。描述一个点时用(x,y)的形式,除开始点外,其他的都要用“->”表示。如果没有一条可行的路则输出-1。

示例输入

5 41 1 0 01 1 1 10 1 1 01 1 0 11 1 1 11 15 4

示例输出

(1,1)->(1,2)->(2,2)->(2,3)->(3,3)->(3,2)->(4,2)->(4,1)->(5,1)->(5,2)->(5,3)->(5,4)(1,1)->(1,2)->(2,2)->(2,3)->(3,3)->(3,2)->(4,2)->(5,2)->(5,3)->(5,4)(1,1)->(1,2)->(2,2)->(3,2)->(4,2)->(4,1)->(5,1)->(5,2)->(5,3)->(5,4)(1,1)->(1,2)->(2,2)->(3,2)->(4,2)->(5,2)->(5,3)->(5,4)(1,1)->(2,1)->(2,2)->(2,3)->(3,3)->(3,2)->(4,2)->(4,1)->(5,1)->(5,2)->(5,3)->(5,4)(1,1)->(2,1)->(2,2)->(2,3)->(3,3)->(3,2)->(4,2)->(5,2)->(5,3)->(5,4)(1,1)->(2,1)->(2,2)->(3,2)->(4,2)->(4,1)->(5,1)->(5,2)->(5,3)->(5,4)(1,1)->(2,1)->(2,2)->(3,2)->(4,2)->(5,2)->(5,3)->(5,4)

 

解析:因为这次走的方式可以上下左右,自然就有可能出现走老路的可能,所以找一个标记每次搜的过程中都标记下路径,递归后再把标记给撤销,就这题而言还要求输出路径,所以就再找个容器把走过的路径存起来。

#include<stdio.h>

#include<string.h>

#include<stdlib.h>

int m,n,f,a[20][20],c[20][20],sx,sy,ex,ey;

int b[100000000]; //存路径

int dfs(int x,int y,int top)

{

    int i;

    b[++top]=x;

    b[++top]=y;  //top也就相当于记录了当前次调用走到哪了;

    if(x==ex&&y==ey)

    {

        f++;

        for(i=1;i<=top;i++)

        {

            if(i%2==0)

            {

            printf("%d)",b[i]);

            if(i!=top)printf("->");

            }

            else

            printf("(%d,",b[i]);

        }

        printf("\n");

        return;

    }

    else

    {

    if(y>1&&c[x][y-1]==0&&a[x][y-1]==1)

    {

        c[x][y-1]=1;  //标记当前点

        dfs(x,y-1,top);

        c[x][y-1]=0;  //撤销标记

    }

    if(x>1&&c[x-1][y]==0&&a[x-1][y]==1)

    {

        c[x-1][y]=1;

        dfs(x-1,y,top);

        c[x-1][y]=0;

    }

    if(y<n&&c[x][y+1]==0&&a[x][y+1]==1)

    {

        c[x][y+1]=1;

        dfs(x,y+1,top);

        c[x][y+1]=0;

    }

    if(x<m&&c[x+1][y]==0&&a[x+1][y]==1)

    {

        c[x+1][y]=1;

        dfs(x+1,y,top);

        c[x+1][y]=0;

    }

    }

    return;

}

int main()

{

    int i,j;

    scanf("%d%d",&m,&n);

    for(i=1;i<=m;i++)

    for(j=1;j<=n;j++)

    scanf("%d",&a[i][j]);

 

    scanf("%d%d",&sx,&sy);

    scanf("%d%d",&ex,&ey);

 

    memset(c,0,sizeof(c));

    c[sx][sy]=1;f=0;

    dfs(sx,sy,0);

    if(f==0)

    printf("-1");

}

 

 

 

 

0 0
原创粉丝点击