题目:小z 的三角形

★实验任务
三角形的第1 行有n 个由“+”和”-“组成的符号,以后每行符
号比上行少1 个,2 个同号下面是”+“,2 个异号下面是”-“ 。
计算有多少个不同的符号三角形,使其所含”+“ 的个数是”-“ 的
个数的一半。n=7 时的1 个符号三角形如下:

+ + - + - + +
+ - - - - +
- + + + -
- + + -
- + -
- -
+

★数据输入
第一行为一个整数N(0<N<=12),表示符合三角形的大小。
★数据输出
输出所有满足题意的图案和总个数(输出的图案按图案中第一行
的字典序排序。例如:n=2 时,按++,+-,-+,--的顺序,因为第一行
为++的图案不符合题意,故样例只输出了+-,-+,--)符号之间以空格
隔开。
输入示例输出示例

2 + -
--
+
--
-
+
3
Hint
可以枚举第一行’+’和’-’的情况来补充完整整个三角形

此题难点在于如何对第一行进行遍历,判断和实现三角形的输出相对比较简单,可以使用异或的方法来做。
这里使用深度优先搜索的函数递归调用来对第一行的每一种情况进行分析进而实现回溯,在每一个节点的位置上,都有+-两种情况,利用递归进行搜索判断。这里参考了汉森和昭锡的代码。
代码1:

#include <cstdio>
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
int f[20][20];
int n;
int ans=0;
void done()//done()函数执行判断和输出符合要求的三角形
{int i,j;for(i=2;i<=n;i++){for(j=1;j<=n-i+1;j++){if(f[i-1][j]!=f[i-1][j+1])f[i][j]=2;else f[i][j]=1;}}int cnt1=0,cnt2=0;for(i=1;i<=n;i++){for(j=1;j<=n-i+1;j++){if(f[i][j]==1)cnt1++;else cnt2++;}}//cout<<cnt1<<" : "<<cnt2<<endl;if(2*cnt1==cnt2)ans++;else return ;for(i=1;i<=n;i++){for(j=1;j<=n-i+1;j++){if(f[i][j]==1)cout<<"+ ";else cout<<"- ";}cout<<endl;}return ;}
void work(int t)
{//cout<<1<<endl;if(t>n){done();return ;}//遇到终点执行done()部分else{f[1][t]=1;t++;work(t);//此时该节点为'+'t--;f[1][t]=2;t++;work(t);//此时该节点为'-'}//实现DFS算法函数递归和判断的部分
}
int main()
{cin>>n;work(1);cout<<ans;return 0;
}

代码1相对较好理解,整串代码的核心是work()函数:

void work(int t)
{//cout<<1<<endl;if(t>n){done();return ;}//遇到终点执行done()部分else{f[1][t]=1;t++;work(t);//此时该节点为'+'t--;//回到位置,归位f[1][t]=2;t++;work(t);//此时该节点为'-'}//实现DFS算法函数递归和判断的部分
}

work()函数分成两个部分:

第一个部分

    if(t>n){done();return ;}//遇到终点执行done()部分

此时无法继续向下搜索,执行done()部分。

第二个部分

    else{
//第一个小节f[1][t]=1;t++;work(t);//此时该节点为'+'
//第二个小节t--;//回到位置,归位
//第三个小节 f[1][t]=2;t++;work(t);//此时该节点为'-'}//实现DFS算法函数递归和判断的部分

虽说只有寥寥几行代码,但确实难以理解。
第二个部分可以分成三个小节:第一个小节代表此时停留的这个节点的状态是+,然后进行向下遍历的操作。第三个小节与第一个小节类似,代表此时停留的这个节点的状态是-。第二个小节t--代表归位(在第一个小节遍历它的所有情况结束以后进行了一次多余的t++操作),从而进行接下来的第三个小节的遍历操作。

大概的意思是,此时该节点的状态如果是+,进行DFS搜索接下来(当这个节点状态是+时)所有的情况,然后返回这个节点,再看这个节点此时的状态如果是-,进行DFS搜索接下来(当这个节点状态是-时)所有的情况,搜索结束以后,这个节点不管状态是+,或是-,它接下来所有的可能性都已经搜索过一遍了。
然后返回这个节点之前的节点,再进行判断。从最末尾开始,一直到最初的起点。

可以想象成一棵树,从它的果实返回到它的一个枝节,从它的枝节返回到树的主干。再从主干返回到根。
大家可以通过草稿纸上的模拟进行理解。

代码2:

#include<stdio.h>
const int MAX_M =15;
const int MAX_N =15;
int ans[MAX_M][MAX_N];
int cnt = 0;void dfs(int n,int i)
{if(i<n+1){ans[1][i]=0;dfs(n,i+1);}else{int j,k;int sum1=0,sum2=0;for(j=2;j<n+1;j++){for(k=1;k<n+2-j;k++){ans[j][k]=ans[j-1][k]^ans[j-1][k+1];//使用异或}}for(j=1;j<n+1;j++){for(k=1;k<n+2-j;k++){if(ans[j][k])sum1++;elsesum2++;}}if(sum1==sum2*2){cnt++;for(j=1;j<n+1;j++){for(k=1;k<n+2-j;k++){if(k==1){if(ans[j][k])printf("-");elseprintf("+");}else if(ans[j][k])printf(" -");elseprintf(" +");}printf("\n");}}return;}ans[1][i] = 1;dfs(n,i+1);return ;
}int main()
{int N;scanf("%d",&N);dfs(N,1);printf("%d\n",cnt);return 0;
}

代码2与代码1的区别在于,它使用了异或来补充三角形。而且把条件判断和输出三角形放在了同一个函数中。

与本题类似的题目:hdoj2510

参考资料:zzy19961112

2016/3/17

DFS回溯-函数递归-xiaoz triangles相关推荐

  1. DFS+回溯算法专题

    基础知识 回溯法是一种选优搜索法(试探法),被称为通用的解题方法,这种方法适用于解一些组合数相当大的问题.通过剪枝(约束+限界)可以大幅减少解决问题的计算量(搜索量). 深度优先搜索(Depth-Fi ...

  2. Leetcode一起攻克搜索(BFS,DFS,回溯,并查集)

    文章目录 BFS简介 DFS简介 回溯简介 并查集简介 DFS题目 690. 员工的重要性 1.dfs解法: 2.bfs算法 547.朋友圈 dfs解法 200.岛屿数量 dfs解法 417.太平洋大 ...

  3. 回溯和递归的区别(简述)

    回溯和递归的区别(简述) 前言 递归和回溯 最后 前言 最近在LeetCode上刷题刷到了递归实现的回溯算法,产生疑惑:这两者有什么区别呢?在网络上阅读了一些相关的文章,总结了一些: 递归和回溯 递归 ...

  4. python 函数递归_Python零基础之三元表达式、函数递归、匿名函数教程!超级详细!...

    目录 一.三元表达式 二.函数递归 递归调用的定义 递归分为两个阶段:递归,回溯 三.匿名函数 什么是匿名函数? 有名字的函数与匿名函数的对比 lambda匿名函数的应用 四.内置函数 #注意:内置函 ...

  5. 学习日记0802函数递归,三元表达式,列表生成式,字典生成式,匿名函数+内置函数...

    1 函数的递归 函数的递归调用时函数嵌套调用的一种特殊形式,在调用的过程中又直接或者间接的调用了该函数 函数的递归调用必须有两个明确的阶段: 1 回溯:函数一次次的调用下去每一次调用,问题的规模都应该 ...

  6. Python基础知识——函数的基本使用、函数的参数、名称空间与作用域、函数对象与闭包、 装饰器、迭代器、生成器与yield、函数递归、面向过程与函数式(map、reduce、filter)

    文章目录 1 函数的基本使用 一 引入 二 定义函数 三 调用函数与函数返回值 2 函数的参数 一 形参与实参介绍 二 形参与实参的具体使用 2.1 位置参数 2.2 关键字参数 2.3 默认参数 2 ...

  7. DSt:数据结构的最强学习路线之数据结构知识讲解与刷题平台、刷题集合、问题为导向的十大类刷题算法(数组和字符串、栈和队列、二叉树、堆实现、图、哈希表、排序和搜索、动态规划/回溯法/递归/贪心/分治)总

    DSt:数据结构的最强学习路线之数据结构知识讲解与刷题平台.刷题集合.问题为导向的十大类刷题算法(数组和字符串.栈和队列.二叉树.堆实现.图.哈希表.排序和搜索.动态规划/回溯法/递归/贪心/分治)总 ...

  8. 4/2 三元表达式/函数递归/匿名函数/内置函数

    三元表达式 def max2(x,y) if x > y: return x else return y res=max2(10,11) 三元表达式仅应用于: 1 条件成立返回一个值 2 条件不 ...

  9. 洛谷 P1219-八皇后(dfs回溯)

    题目描述 网址传送:https://www.luogu.com.cn/problem/P1219 八皇后问题描述:介是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于 ...

最新文章

  1. UA MATH567 高维统计 专题0 为什么需要高维统计理论?——高维统计理论的常用假设
  2. 支持常见数据库差异对照说明
  3. Elasticsearch 架构原理
  4. php os darwin,解决Mac os(10.12.6) 编译php7提示“/usr/lib/system/libsystem_darwin.dylib”找不到...
  5. php 数组降维,php 数组去重的方法参考(一维数组去重、二维数组去重)
  6. mongoose 数据库设计千万要注意 Cast to [number] failed for value
  7. LeetCode(657)——机器人能否返回原点(JavaScript)
  8. kotlin内联函数_Kotlin内联函数,参数化
  9. sp_executesq用法
  10. Show一下2008新技术体验活动的奖品
  11. AxureRP9(team版)安装+汉化+秘钥
  12. QQ在线客服代码演示-asp源代码
  13. java.lang.IllegalArgumentException: requirement failed: indices should be one-based and in ascending
  14. dtm文件生成等高线 lisp_CAD2000下DTM的建立
  15. 银行账户管理体系总结
  16. Ubuntu网络连接激活失败
  17. 管道的故事(一)管道的故事
  18. iptables配置docker服务端口访问限制
  19. Java jdk 在线文档(可搜索类)
  20. 免费音乐素材网站推荐 视频剪辑自媒体运营必备

热门文章

  1. nodejs mongodb
  2. 如何使用报表工具设置页眉与页脚
  3. MongoDB命令笔记
  4. 新技术预研Android
  5. 高中生参加的计算机奥赛是,高中生可参加哪些含金量较高的赛事?报名流程指南来了!...
  6. 关于『数据结构』:图论
  7. 2022年下半年软件设计师考试下午真题(专业解析+参考答案)
  8. HTML5面试题总结
  9. 微信小程序流量主广告怎么加圆角
  10. 局部边缘保留滤波器LEP算法原理及matlab代码实现