经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C++ » 查看文章
2018NOIP普及T4---对称二叉树
来源:cnblogs  作者:resftlmuttmotw  时间:2018/12/3 10:13:35  对本文有异议

 题目 对称二叉树

  
   题目描述

 

思路

  检查是否符合对称条件

    条件很简单——结构对称&&点权对称

    要做到点权对称其实也就顺便结构对称了

    于是条件可以简化为点权对称

    可以考虑并行搜索

  1. 1 bool con(int l,int r) {
  2. 2 if(l == -1&&r == -1)
  3. 3 return 1;
  4. 4 if(l == -1||r == -1)
  5. 5 return 0;
  6. 6 if(w[l] == w[r])
  7. 7 if(check(l,r))
  8. 8 return 1;
  9. 9 return 0;
  10. 10 }
  11. 11 bool check(int x,int y) {
  12. 12 if(x == -1&&y == -1)
  13. 13 return 1;
  14. 14 if(x == -1||y == -1)
  15. 15 return 0;
  16. 16 if(w[x] != w[y])
  17. 17 return 0;
  18. 18 int l = Root[x].l,l1 = Root[y].l;
  19. 19 int r = Root[y].r,r1 = Root[x].r;
  20. 20 if(con(l,r)&&con(l1,r1))
  21. 21 return 1;
  22. 22 return 0;
  23. 23 }

  信仰深搜

    就三个点

  

    你就装作上面还有一个点

  

  1. 1 int dfs(int x) {
  2. 2 if(x == -1) return 0;
  3. 3 if(check(Root[x].l,Root[x].r)) {
  4. 4 int ans = Find(x) + 1;
  5. 5 return ans;
  6. 6 }
  7. 7 int ans = max(dfs(Root[x].l),dfs(Root[x].r));
  8. 8 return ans;
  9. 9 }

  找答案

    加一指根节点

  1. 1 int Find(int x) {
  2. 2 int q = 0;
  3. 3 int l = Root[x].l;
  4. 4 int r = Root[x].r;
  5. 5 if(l != -1) q += Find(l) + 1;
  6. 6 if(r != -1) q += Find(r) + 1;
  7. 7 return q;
  8. 8 }

  另外
    读入时要记录这样几个玩意儿

  

  1. 1 for(i = 1;i <= n;i++)
  2. 2 scanf("%d",&w[i]);
  3. 3 for(i = 1;i <= n;i++)
  4. 4 scanf("%d%d",&Root[i].l,&Root[i].r);

  code

 

  1. 1 #include<cstdio>
  2. 2 #include<cstring>
  3. 3 #include<iostream>
  4. 4 #include<algorithm>
  5. 5 #define M 1000001
  6. 6 using namespace std;
  7. 7 int w[M];
  8. 8 struct N {
  9. 9 int l,r;
  10. 10 }Root[M];
  11. 11 bool con(int,int);
  12. 12 bool check(int,int);
  13. 13 //两个函数相互递归调用,并行搜索检查是否符合要求
  14. 14 int dfs(int);
  15. 15 //核心
  16. 16 int Find(int);
  17. 17 //其实就是找有多少个点
  18. 18 int main() {
  19. 19 int i,n;
  20. 20 scanf("%d",&n);
  21. 21 for(i = 1;i <= n;i++)
  22. 22 scanf("%d",&w[i]);
  23. 23 for(i = 1;i <= n;i++)
  24. 24 scanf("%d%d",&Root[i].l,&Root[i].r);
  25. 25 int ans = dfs(1);
  26. 26 printf("%d",ans);
  27. 27 return 0;
  28. 28 }
  29. 29
  30. 30 bool con(int l,int r) {
  31. 31 if(l == -1&&r == -1)
  32. 32 return 1;
  33. 33 if(l == -1||r == -1)
  34. 34 return 0;
  35. 35 if(w[l] == w[r])
  36. 36 if(check(l,r))
  37. 37 return 1;
  38. 38 return 0;
  39. 39 }
  40. 40 bool check(int x,int y) {
  41. 41 if(x == -1&&y == -1)
  42. 42 return 1;
  43. 43 if(x == -1||y == -1)
  44. 44 return 0;
  45. 45 if(w[x] != w[y])
  46. 46 return 0;
  47. 47 int l = Root[x].l,l1 = Root[y].l;
  48. 48 int r = Root[y].r,r1 = Root[x].r;
  49. 49 if(con(l,r)&&con(l1,r1))
  50. 50 return 1;
  51. 51 return 0;
  52. 52 }
  53. 53 int Find(int x) {
  54. 54 int q = 0;
  55. 55 int l = Root[x].l;
  56. 56 int r = Root[x].r;
  57. 57 if(l != -1) q += Find(l) + 1;
  58. 58 if(r != -1) q += Find(r) + 1;
  59. 59 return q;
  60. 60 }
  61. 61 int dfs(int x) {
  62. 62 if(x == -1) return 0;
  63. 63 if(check(Root[x].l,Root[x].r)) {
  64. 64 int ans = Find(x) + 1;
  65. 65 return ans;
  66. 66 }
  67. 67 int ans = max(dfs(Root[x].l),dfs(Root[x].r));
  68. 68 return ans;
  69. 69 }

 

总结

    信仰很重要

    这代码很慢但不至于卡常,还有大量可优化地方,此处不再赘述

    它非常好理解,相信任何人都能写出比这更优秀的代码

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号