蓝桥杯---剪邮票---DFS的适用范围

2023-10-25 19:10
文章标签 蓝桥 dfs 邮票 适用范围

本文主要是介绍蓝桥杯---剪邮票---DFS的适用范围,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!



                                                  剪邮票

【题意】
           如【图1.jpg】, 有12张连在一起的12生肖的邮票。
           现在你要从中剪下5张来,要求必须是连着的。
          (仅仅连接一个角不算相连)
           比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。

           请你计算,一共有多少种不同的剪取方法。

           请填写表示方案数目的整数。

           注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。


                      图1


                          图2


                        图3


【分析】

        本题刚开始以为是一个简单DFS搜索,就考一个去重,当时以为可以3个方向遍历就能起到去重的效果,

    但最后和别人比较发现答案少了很多数据,然后开始研究别人的代码,发现了很多有趣的东西,打了这么久

    的DFS竟然不知道这题不能光一个DFS解决(也有不了解题意的原因)。越想越感觉到DFS对有些题的不适

    应性。


   DFS代码实现的功能

           (以前从没考虑过这,但是现在一考虑确实有很多代码细节,原来DFS是这么起到独特的搜索作用)

             DFS的实现是一直递归递归到走不动或满足某种条件,才会返回回溯,取消路上的标记(回溯取消,

     有些题不回溯就不用取消,这里主要讨论的回溯情况)。

             本题剪邮票类似DFS搜索方式,但又不是DFS方式。

             因为剪连续邮票,可以是一个点的多个分支,就比如最小水池数问题(只是最小水池数不用回溯)。

             DFS最多只能选择一个点的两个方向进行遍历(上个点来的方向和下个点的方向),虽然for循环看

      似枚举4个方向,但是他只能选择一个方向走,不能同时选择俩进行遍历。


 DFS的不适用范围

               当遇到要在地图中选块且需要回溯(大多是求地图满足某个条件的总数)的题目时,一个DFS就不

       能解决此类问题此题可以看出DFS不适合遍历时可以选一个点3个方向及其以上的状况,你无法确定这个

       方向选多少点和那个方向选多少个点正好N个点,取消标记也会很复杂。

              无论怎么DFS都无法实现(这里太绝对,DFS可以做到但是太难实现,一般涉及到这的就可以选择别

       的算法去实现,会比DFS做简单很多),因为每个点的不同方向可能有很多相同的点,选好了怎么回溯是

       一个难以解决的问题。就很像一个树的结点去遍历他的子树一样,你不可能把所有子树中N个结点遍历完,

      再取消标记,要想把子树中遍历标记的结点取消标记,需要另建一个数组专门保存哪些点在这次被标记了。


【代码】


      

#include<stdio.h>
#include<string.h>
int num,cnt,vis[10][10],book[10][10],ans[10];
int fang[4][2]={-1,0,0,-1,0,1,1,0};// 函数功能:判断选取的k个生肖是否是连续的
void dfs2(int x,int y)
{vis[x][y]=1;cnt++;for(int i=0;i<4;i++){int tx,ty;tx=x+fang[i][0];ty=y+fang[i][1];if(tx<1||tx>3||ty<1||ty>4||!book[tx][ty]||vis[tx][ty]) continue;dfs2(tx,ty);}return ;
}
// 函数功能:实现选取由k的生肖组成的所有可能,选取的生肖序号从小到大选取,起到了判重的作用
void dfs(int k)
{if(k==6){int x=(ans[1]-1)/4+1;int y=(ans[1]-1)%4+1;memset(vis,0,sizeof(vis));cnt=0;dfs2(x,y);if(cnt==5)num++;}for(int i=ans[k-1]+1;i<13;i++) // 比上一个选取的编号要大,起到判重的作用{int x=(i-1)/4+1;int y=(i-1)%4+1;book[x][y]=1;ans[k]=i;dfs(k+1);book[x][y]=0;}
}int main()
{dfs(1);printf("%d\n",num);
}


【收获】

     1.      打了这些久的DFS,一直觉得是模板没怎么去仔细思考,现在遇到了问题,仔细想来DFS代码这么

           的经典。

       2.   懂得了什么时候不是一个DFS搜索能解决的,DFS的适应范围。

       3.    许多经典的算法虽然会用但为什么会实现这个功能或者它隐藏着什么细节都需要去挖掘



以上全是自己的思想,如果有什么不对的地方请留言,谢谢


这篇关于蓝桥杯---剪邮票---DFS的适用范围的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/284619

相关文章

hdu 2489 (dfs枚举 + prim)

题意: 对于一棵顶点和边都有权值的树,使用下面的等式来计算Ratio 给定一个n 个顶点的完全图及它所有顶点和边的权值,找到一个该图含有m 个顶点的子图,并且让这个子图的Ratio 值在所有m 个顶点的树中最小。 解析: 因为数据量不大,先用dfs枚举搭配出m个子节点,算出点和,然后套个prim算出边和,每次比较大小即可。 dfs没有写好,A的老泪纵横。 错在把index在d

poj 3050 dfs + set的妙用

题意: 给一个5x5的矩阵,求由多少个由连续6个元素组成的不一样的字符的个数。 解析: dfs + set去重搞定。 代码: #include <iostream>#include <cstdio>#include <set>#include <cstdlib>#include <algorithm>#include <cstring>#include <cm

ural 1149. Sinus Dances dfs

1149. Sinus Dances Time limit: 1.0 second Memory limit: 64 MB Let  An = sin(1–sin(2+sin(3–sin(4+…sin( n))…) Let  Sn = (…( A 1+ n) A 2+ n–1) A 3+…+2) An+1 For given  N print  SN Input One

hdu 6198 dfs枚举找规律+矩阵乘法

number number number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description We define a sequence  F : ⋅   F0=0,F1=1 ; ⋅   Fn=Fn

深度优先(DFS)和广度优先(BFS)——算法

深度优先 深度优先搜索算法(英语:Depth-First-Search,DFS)是一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支,当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访

C语言蓝桥杯

一、语言基础 竞赛常用库函数 最值查询 min_element和max_element在vector(迭代器的使用) nth_element函数的使用 例题lanqiao OJ 497成绩分析 第一种用min_element和max_element函数的写法 第二种用min和max的写法 二分查找 二分查找只能对数组操作 binary_s

nyoj99(并查集+欧拉路+dfs)

单词拼接 时间限制: 3000 ms  |  内存限制: 65535 KB 难度: 5 描述 给你一些单词,请你判断能否把它们首尾串起来串成一串。 前一个单词的结尾应该与下一个单词的道字母相同。 如 aloha dog arachnid gopher tiger rat   可以拼接成:aloha.arachnid.dog.gopher.rat.tiger 输入 第一行是一个整

【CF】E. Anya and Cubes(双向DFS)

根据题意的话每次递归分3种情况 一共最多25个数,时间复杂度为3^25,太大了 我们可以分2次求解第一次求一半的结果,也就是25/2 = 12,记录结果 之后利用剩余的一半求结果 s-结果 = 之前记录过的结果 就可以 时间复杂度降低为 3 ^ (n/2+1) 题目链接:http://codeforces.com/contest/525/problem/E #include<set

力扣 797. 所有可能路径【DFS】

1. 题目 2. 代码 DFS , 直接见代码 class Solution {public:vector<int> path;vector<vector<int>> res; // 结果集void dfs(vector<vector<int>>& graph, int cur, int n){// 找出所有从节点 0 到节点 n-1 的路径// 下标从 0 开始的if (

CF Bayan 2015 Contest Warm Up B.(dfs+暴力)

B. Strongly Connected City time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output 题目链接: http://codeforces.com/contest/475/probl