第一天总结(dfs方面)

每日总结:

1.迷宫问题

https://www.luogu.com.cn/problem/P1605

题目描述:

给定一个 N \times MN×M 方格的迷宫,迷宫里有 TT 处障碍,障碍处不可通过。

在迷宫中移动有上下左右四种方式,每次只能移动一个方格。数据保证起点上没有障碍。

给定起点坐标和终点坐标,每个方格最多经过一次,问有多少种从起点坐标到终点坐标的方案。

代码如下:

#include <stdio.h>

int mg[100][100];
int n,m,t,sx,sy,fx,fy;
int count;//可以到达终点的方案数 

void dfs(int x,int y)
{
    if(mg[x][y]==1)return;//走过或是障碍物 
    if(x<1||x>n||y<1||y>m)return;//处理边界问题 
    if(x==fx&&y==fy){
        count++;
        return;
    }//坐标与终点坐标相同,到终点的方法数加一 
    mg[x][y]=1;//1用于表示障碍物或者是已经走过 
    dfs(x,y+1);//右 
    dfs(x+1,y);//下 
    dfs(x,y-1);//左 
    dfs(x-1,y);//上 
    mg[x][y]=0;//回溯,还原状态 
}
 
void input()
{    
    int p,q;
    scanf("%d%d%d",&n,&m,&t);
    scanf("%d%d%d%d",&sx,&sy,&fx,&fy);
    for(int i=0;i<t;i++)
    {
        scanf("%d%d",&p,&q);
        mg[p][q]=1;//对障碍物所在的位置赋1 
    }
}//用于输入数据 
 
int main(int argc, char *argv[])
{
    input();
    dfs(sx,sy);
    printf("%d\n",count);
    return 0;
}

首先全局数组内的值都为0,我们再将有障碍物的位置置1,然后从起点处开始向我们给定的方向顺序移动(我这里是右->下->左->上),但在这之前还要先判断当前位置是否能够到达(不超边界,没有障碍),当该位置能到时,就先置1,代表走过了,然后递归到可移动的位置,在不能动的情况下,回溯到上一个位置,然后换一个方向位移,直到抵达终点,方案数加一,然后回溯到上一个位置,看看有没有其他的方向可以走通,将各位置的所有方向全部探测完毕后,程序结束。

2.自然数拆分

https://www.luogu.com.cn/problem/P2404

题目描述:

任何一个大于 11 的自然数 nn,总可以拆分成若干个小于 nn 的自然数之和。现在给你一个自然数 nn,要求你求出 nn 的拆分成一些数字的和。每个拆分后的序列中的数字从小到大排序。然后你需要输出这些序列,其中字典序小的序列需要优先输出。

代码如下:

#include <stdio.h>

int m;//m用来记录n的值 
int a[9]={1};
//第一个元素为一表示的是从1开始拆分 

void print(int step)//step表示拆分了几个数 
{
    int i;
    for(i=1;i<step;i++)printf("%d+",a[i]);
    printf("%d\n",a[i]);
}

void dfs(int n,int step)
{
    for(int i=a[step-1];i<=n;i++)//升序输出,后面的数不能小于前面 
    {
        if(i<m)
        {
            a[step]=i;//记录拆分出来的数 
            n-=i;//n为剩下要拆分的数 
            if(n==0)print(step);//数已经拆分完,打印记录的数据 
            else dfs(n,step+1);
            n+=i;//回溯后要还原状态 
        }
    }
}

int main(int argc, char *argv[])
{
    int n;
    scanf("%d",&n);
    m=n; 
    dfs(n,1);
    return 0;
}

第一轮拆分后肯定将全是1,到了第二轮开始回溯,此时a从第二个元素开始为{1,1,1,1,1},n的值为2,因此将倒数第二个位置记录为2,n-2后为0,再次打印出来,然后又回溯,a{1,1,1,1},n的值为3,这里也是从2开始,但是将倒数第三的位置上记录了2后,n就只剩下了1,到了下一个位置后前一个数的值2比1要大,还是不行,然后回溯上去,将倒数第三的位置上记录上3,n-3后为0,将其打印出来,剩下的以此类推,最终完成所有拆分结果。

在Python中实现深度优先搜索(DFS)通常涉及到递归函数的编写。深度优先搜索是一种用于遍历或搜索树或图的算法。这个算法会尽可能深地搜索树的分支。当节点v的所在边都已被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这个过程一直进行到已发现从源节点可达的所有节点为止。 以下是一个简单的深度优先搜索函数的示例,用于遍历图结构: ```python def dfs(graph, start, visited=None): if visited is None: visited = set() visited.add(start) # 将起始节点标记为已访问 print(start) # 处理当前节点,例如打印节点值 for next_node in graph[start]: # 遍历所有邻接节点 if next_node not in visited: dfs(graph, next_node, visited) # 递归访问未访问的邻接节点 return visited # 示例图的邻接表表示 graph = { 'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F'], 'D': [], 'E': ['F'], 'F': [] } # 开始深度优先搜索,从节点 'A' 开始 dfs(graph, 'A') ``` 在这个例子中,`graph` 是一个字典,它的键是节点,值是与该节点直接相连的节点列表。`start` 是搜索的起点。`visited` 参数是一个集合,用来记录已访问过的节点,以避免重复访问。 DFS函数的工作流程如下: 1. 将当前节点标记为已访问,并对其进行处理(例如打印或添加到结果列表)。 2. 对于当前节点的每个未访问的邻接节点,递归调用DFS函数。 3. 重复这个过程,直到所有节点都被访问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值