关于DFS几道比较基础的题

图的深度优先搜索DFS 图的深度优先搜索 阅读详情
  1. 题目一 FatMouse and Cheese
    题目大意就是说有一个老鼠在N*N的网格当中每一步最多只能走K格 并且由于猫的存在每一次老鼠的移动都必须比路径上一个网格收集的奶酪多 问这条路径上老鼠收集的奶酪最大值
Sample Input
3 1
1 2 5
10 11 6
12 12 7
-1 -1
Sample Output
37

PS: 终点的位置不是固定的 满足上下左右都不存在比当前更大的网格的条件 即四周都比当前网格值小

#include<bits/stdc++.h>
using namespace std;

const int maxn=105;
int n,k,nx,ny;
int vis[maxn][maxn],dp[maxn][maxn];
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
int dfs(int x,int y)
{
    int i,j,nx,ny,ans=0;
    if(dp[x][y])
        return dp[x][y];//联系到第二个return 即已经进行赋值表示找到了最大路径
    for(i=0;i<4;i++)
    {
        for(j=1;j<=k;j++)
        {
            nx=x+j*dx[i];//每次移动1~k个网格
            ny=y+j*dy[i];
            if(nx>0&&nx<=n&&ny>0&&ny<=n&&vis[nx][ny]>vis[x][y])
            {
                ans=max(ans,dfs(nx,ny));//一直往(nx,ny)的方向递归找最大路径
            }
        }
    }
    return dp[x][y]=ans+vis[x][y];//已经走到了终点加上终点的值
}
int main()
{
    int i,j;
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        if(n==-1&&k==-1)
            break;
        memset(dp,0,sizeof(dp));
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
                scanf("%d",&vis[i][j]);
        printf("%d\n",dfs(1,1));
    }
    return 0;
}
  1. 题目二 字符的全排列问题 有n个字符 请你输出该n个字符的全排列
Sample Input
1
abc
Sample Output
a b c
a c b
b a c
b c a
c a b
c b a
#include<stdio.h>
#include<string.h>

int n;
char  a[15];
char re[15];
int vis[15];
void dfs(int step)
{
    int i;
    if(step==n+1)//判断边界
    {
        for(i=1;i<=n;i++)
            printf("%c",re[i]);
        printf("\n");
        return ;
    }
    for(i=1;i<=n;i++)//遍历每一种情况
    {
        if(vis[i]==0)//check满足
        {
            re[step]=a[i];
            vis[i]=1;//标记
            dfs(step+1);//继续搜索
            vis[i]=0;//恢复初始状态
        }
    }
    return ;
}

int main(void)
{
    int T;
    scanf("%d",&T);
    getchar();
    while(T--)
    {
        memset(a,0,sizeof(a));
        memset(vis,0,sizeof(vis));//对存数据的数组分别初始化
        scanf("%s",a+1);
        n=strlen(a+1);
        dfs(1);//从第一个箱子开始
    }
    return 0;
}

3.题目三 走迷宫

Sample Input
10 12
W…WW.
.WWW…WWW
…WW…WW.
…WW.
…W…
…W…W…
.W.W…WW.
W.W.W…W.
.W.W…W.
…W…W.

Sample Output
3

题目大意:w代表池塘 -代表水洼 八连通时表示该池塘积水 问有多少积水的池塘
用dfs搜索W的周围 若周围有w 则置为- 直到搜索完所有的点 图中剩下的就是积水池塘的个数

#include<bits/stdc++.h>
using namespace std;

const int maxn=1e2+10;

int num=0,nx,ny,n,m;
char mp[maxn][maxn];
int dx[]={0,1,0,-1,0};
int dy[]={0,0,1,0,-1};
void dfs(int x,int y)
{
    int i,j;
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=m;j++)
        {
            nx=x+dx[i];
            ny=y+dy[i];
            if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&mp[nx][ny]=='W')
            {
                mp[x][y]='.';
                dfs(nx,ny);
            }
        }
    }

}
int main()
{
    int i,j;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(i=1;i<=n;i++)
            for(j=1;j<=m;j++)
              scanf("%c",&mp[i][j]);
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                if(mp[i][j]=='W')
                {
                    dfs(i,j);
                    num++;
                }
            }
        }
        printf("%d\n",num);
    }
    return 0;
}

4.题目四 How many ways
这是一个简单的生存游戏,你控制一个机器人从一个棋盘的起始点(1,1)走到棋盘的终点(n,m)。游戏的规则描述如下:
1.机器人一开始在棋盘的起始点并有起始点所标有的能量。
2.机器人只能向右或者向下走,并且每走一步消耗一单位能量。
3.机器人不能在原地停留。
4.当机器人选择了一条可行路径后,当他走到这条路径的终点时,他将只有终点所标记的能量

机器人一开始在(1,1)点,并拥有4单位能量,蓝色方块表示他所能到达的点,如果他在这次路径选择中选择的终点是(2,4) 点,当他到达(2,4)点时将拥有1单位的能量,并开始下一次路径选择,直到到达(6,6)点。
我们的问题是机器人有多少种方式从起点走到终点。这可能是一个很大的数,输出的结果对10000取模。

Sample Input
1
6 6
4 5 6 6 4 3
2 2 3 1 7 2
1 1 4 6 2 7
5 8 4 3 9 5
7 6 6 2 1 5
3 1 1 3 7 2
Sample Output
3948

刚开始我的代码走的路径是上下左右然后选择比当前储存能量小的点搜下去直到终点 不过题目中表明了机器人只能往右或往下走 因此我们只要从左上角一只搜到右下角 然后右下角中的点储存的值就是我们最终的路径总数了

#include<stdio.h>
#define p 10000

int mp[120][120],vis[120][120];
int n,m,nx,ny;
long long dfs(int x,int y)
{
    if(x==n&&y==m)//从起点走到了终点 只搜索了一次 总共也就只有一条路径
        return 1;
    if(vis[x][y]!=0)//所有点都尝试了以后输出最终的路径总数
        return vis[x][y];
    vis[x][y]=0;
    for(int i=0;i<=mp[x][y];i++)//mp[x][y]是机器人当前的能量 而它要往下或往右走的格子是在当前能量够用的情况
    {                          //每走一步机器人将消耗一个能量
        for(int j=0;j<=mp[x][y]-i;j++)
        {
            nx=x+i;
            ny=y+j;
            if((i!=0||j!=0)&&nx>=1&&nx<=n&&ny>=1&&ny<=m)//i,j不为零的意思是走的路不可能再加上起点
            {
                vis[x][y]+=dfs(nx,ny);
                vis[x][y]%=p;
            }
        }
    }
    return vis[x][y];
}
int main()
{
    int T,i,j;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                scanf("%d",&mp[i][j]);
                vis[i][j]=0;//初始化 vis用来存放路径总数
            }
        }
        printf("%lld\n",dfs(1,1));
    }
    return 0;
}

  1. Dividing
Sample Input
1 0 1 2 0 0 
1 0 0 0 1 1 
0 0 0 0 0 0 
Sample Output
Collection #1:
Can't be divided.

Collection #2:
Can be divided.

没想到这道题居然还能使用广搜的方法来做 之前用的是dp(转换成多重背包)
广搜代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>

using namespace std;

#define N 2400
#define INF 0x3f3f3f3f//正无穷大
#define PI acos (-1.0)
#define EPS 1e-8
#define met(a, b) memset (a, b, sizeof (a))
 
typedef long long LL;
 
int a[N], half, flag;
 
void DFS (int v, int Index)
{
    if (v == half)
    {
        flag = 1;
        return;
    }
 
    for (int i=Index; i>=1; i--)
    {
        if (a[i])
        {
            if (v + i <= half)
            {
                a[i]--;
                DFS (v+i, i);
 
                if (flag) break;
            }
        }
    }
    return;
}
 
int main ()
{
    int nCase = 1;
 
    while (scanf ("%d %d %d %d %d %d", &a[1], &a[2], &a[3], &a[4], &a[5], &a[6]))
    {
        int sum = a[1]+a[2]*2+a[3]*3+a[4]*4+a[5]*5+a[6]*6;
 
        if (!sum) break;
 
        printf ("Collection #%d:\n", nCase++);
 
        if (sum % 2)
        {
            puts ("Can't be divided.\n");
            continue;
        }
 
        flag = 0;
 
        half = sum / 2;
        DFS (0, 6);
 
        if (flag) puts ("Can be divided.");
        else puts ("Can't be divided.");
        puts ("");
    }
    return 0;
}

多重背包代码//这个好理解一些

#include<bits/stdc++.h>
using namespace std;

const int mmax=50000;
int f[mmax],k[mmax],v[7]= {0,1,2,3,4,5,6},a[mmax];
int main()
{
	int i,j,op;
    for(op=1;;op++)
    {
        memset(f,0,sizeof(f));
        int sum=0;
        for(i=1; i<=6; i++)
        {
            scanf("%d",&k[i]);
            sum+=k[i]*i;
            v[i]=i;
        }
        if(sum==0)
          break;
        int hh=sum;
        if(sum%2==1)
            printf("Collection #%d:\nCan't be divided.\n\n",op);
        int index=0;
        if(sum%2==0&&hh!=0)
        {
            for(i=1; i<=6; i++)
            {
                for(j=1;j<=k[i];j*=2)
                {
                    a[++index]=j*v[i];
                    k[i]-=j;
                }
                if(k[i]>0)
                  a[++index]=v[i]*k[i];
            }
            sum/=2;
            for(i=1; i<=index; ++i)
            {
                for(j=sum; j>=a[i]; --j)
                    f[j]=max(f[j],f[j-a[i]]+a[i]);
            }
            if((hh-f[sum])!=sum)
                printf("Collection #%d:\nCan't be divided.\n\n",op);
            if((hh-f[sum])==sum)
                printf("Collection #%d:\nCan be divided.\n\n",op);
        }
    }
    return 0;
}
深度优先搜索DFS-从入门到精通【卡玛】 没有理论基础的先看卡哥讲解的,很通俗易懂~,简单概括📌深度优先搜索(Depth First Search,简称 DFS)是一种在图或树等数据结构中遍历节点的算法。它沿着一个方向不断深入,直到无法继续为止,然后回溯并探索其他路径。本篇主要介绍dfs的代码实现,并枚举总结了几道经典例。之前我跟着yxc大佬学习的dfs 也发表总结了相关博客 ,(ps:总感觉存储结构很复杂,到现在再看已经看不懂了哈哈哈) 阅读详情

相关推荐

HDU---1078---FatMouse and Cheese---记忆化DFS

目描述: Fatmouse在一个城市储存了一些奶酪。该市可以被认为是尺寸N的方形网格:每个网格位置标记(p,q),其中0 <= p <n和0 <= q <n。在每个网格位置,Fatmouse在一个洞中有0到100块奶酪。现在他会享受他最喜欢的食物。 Fatmouse始于站在位置(0,0)。他吃了他站立的奶酪,然后水平或垂直地运行到另一个位置。问是,有一只名叫顶级杀手的超级猫坐在他的洞附近,所以每次他都可以在最多的k个位置跑到洞穴之前被顶级杀手抓住。更糟糕的是 , 在一个地点吃奶

weixin_45102820的博客 514

FatMouse and Cheese---老鼠和奶酪

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1107 FatMouse has stored some cheese in a city. The city can be considered as a square grid of dimension n: each grid location is labe...

嵩韵儿 622

FatMouse and Cheese

FatMouse and Cheese记忆化FatMouse has stored some cheese in a city. The city can be considered as a square grid of dimension n: each grid location is labelled (p,q) where 0 <= p < n and 0 <=...

rg_lzm的博客 547

HDU 1078 FatMouse and Cheese报告

dfs+dp(记忆化搜索

Lur 's acm blog 1520

深度优先算法

深度优先算法 前言 深度优先是遍历图的一种算法,对于我们解蓝桥杯的目,我们可以不懂图是什么,他是怎样遍历图。对于蓝桥杯来说他就是一种暴力的算法,就是一种将很多层for循环化成递归的方法,用于爆破来解一些问。他是蓝桥杯的必考考点,希望大家务必掌握,这种目一般有俩种类型,排列和组合。下面我们通过几道目来了解这个算法。 排序例 目背景 猪猪hanke得到了一只鸡 目描述 猪猪Hanke特别...

qq_36310758的博客 831

深度优先搜索dfs)练习及详细解答

相信很多人在最先开始学习深度优先搜索dfs)的时候,都是一脸懵逼,但其实只要通过一定数目的练习,你就可以熟练运用这一算法(骗分神器)了,下面是我挑选出的几道dfs目(源自洛谷),相信你练习完了以后,对这一神奇算法也会有更深的体会。 首先是一道dfs的入门: 下面是代码 ...

weixin_45725925的博客 4407

你还不会暴力搜索吗,dfs(深度优先搜索)详解,看这一篇就够啦

DFS算法的基本思想是从图中的某个顶点v出发,访问此顶点,然后依次从v的未被访问的邻接点出发深度优先遍历图,直至图中所有和v有路径相通的顶点都被访问到。若此时图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作起始点,重复上述过程,整个进程反复进行直到所有顶点都被访问为止。指数型枚举是指一共有n个数,每一个数都有两种状态,也就是选或不选,时间复杂度也就是2^n,指数级的。

2202_76097976的博客 7160

深度优先算法(二) 一些例加深对DFS的理解

我在三天前写了一篇文章: 深度优先算法入门(超级简单的例入门) 当然只理解概念是不行的,我们就做几道相似的目来加深一下对DFS的理解吧。 一、46. Permutations 给定一个 没有重复 数字的序列,返回其所有可能的全排列。 示例: 输入: [1,2,3] 输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], ...

刷刷刷,刷Leetcode 259

【刷】备战蓝桥杯 — dfs 算法

本文讲解了dfs 算法,讲解了三道经典目,并解决了一道蓝桥杯省赛真

叫我龙翔的博客 3683

浅谈 DFS(深度优先搜索) 也许是最最最最基础的讲解了Orz

1

qq_45447132的博客 2774

【算法】深度优先搜索DFS

  深度优先搜索是笔试面试中重点考察的内容。今天来讲解深度优先搜索的思想。这里推荐阅读《算法笔记》这本数,对考研机试和找工作中笔试面试常考算法都进行了通俗的讲解。公众号回复 801 获取 pdf。   深度优先搜索的思路很简单,以当前位置为起点,沿着一条路向前走,遇到岔路口,选择一条岔路前进。如果选择的这个岔路是死路(遇到了递归边界),那么就退回到刚刚的岔路口,选择另一个岔路口前进。如果岔路中存在新的岔路,那么也按照刚刚的方法枚举。这样一定能找到出口(目标解存在的情况下)。由于这种方法是不到死路(递归边界)

每天更新大数据面经和技术 1392

关于深度优先搜索(DFS) 与 选择问

本篇主要梳理深度优先搜索与选择问之间的联系,深剖解规律。之前的接触到的搜索都是纯粹的搜索 ,直接就是路径问。经过这两天的练习我发现DFS在选择问上是个不错的解决方法。在路径问上,由于要找到好的路径,所以DFS必须要把所有的路径都找一遍。而到了选择问,经过简单的转变DFS也可以将所有的选择方案给找出来。路径问中通过不同的拐点有不同的路,而选择问中每次不同的选择也代表了一次"拐点"。写了几道发现其实这类有一定的解规律,下次遇到此类型的时可以向搜索靠拢。

TS & c++ 1004

洛谷搜索(BFS,DFS)

好久没有写搜索了,模板都忘了。今天做了几道复习了一下,分别写篇DFS和BFS解巩固一下。

TS & c++ 961

蓝桥杯——深搜DFS(看完绝对入门DFS

一文详解DFS,看完绝对入门(附练习和详解)

m0_47963315的博客 6350

深度优先搜索DFS练习

深度优先搜索,其实不用想的特别复杂,把思路交给计算机,然后让它一条道走到黑就是了。 下面给出几道经典例讲解。 第一 有一是说,有一个大家族,有n个人编号是1-n(他们互为父子),n-1对父子关系,每次输入两个数a,b代表a是b的父亲,然后让你计算出这n个人中每个人有多少后代。(注:只有一个祖先) 直接上代码 #include <iostream> #include <c...

weixin_45938281的博客 219

深度优先搜索DFS

深度优先搜索也就是DFS,使我们oi竞赛中使用的最多的算法之一 我们今天就来看下这个神奇的算法 1.什么是DFS 事实上,深度优先搜索属于图算法的一种,英文缩写为DFS即Depth First Search.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次 2.DFS有什么用 其实这个DFS往往用来遍历一幅图,在树剖、网络流等算法中会用到。它还可以用来...

amunnku8163的博客 94
上一篇: 欧拉函数模板
下一篇: 51nod 1119 组合数
qq_970313613
博客等级 码龄11年 4粉丝 41原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值