题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5573

这个题……规律暂时还找不到,先贡献两发TLE的代码吧,一个dfs一个状压枚举。

  1. #include <algorithm>
  2. #include <iostream>
  3. #include <iomanip>
  4. #include <cstring>
  5. #include <climits>
  6. #include <complex>
  7. #include <fstream>
  8. #include <cassert>
  9. #include <cstdio>
  10. #include <bitset>
  11. #include <vector>
  12. #include <deque>
  13. #include <queue>
  14. #include <stack>
  15. #include <ctime>
  16. #include <set>
  17. #include <map>
  18. #include <cmath>
  19.  
  20. using namespace std;
  21.  
  22. typedef long long ll;
  23. const int maxn = ;
  24.  
  25. ll n, k;
  26. ll path[maxn][];
  27. int pcnt;
  28. //1 + 0 -
  29. bool exflag;
  30. void dfs(ll cur, ll lv, ll id) {
  31. if(exflag) return;
  32. if(cur == n && lv == k) {
  33. for(ll i = ; i < pcnt; i++) {
  34. printf("%I64d %c\n", path[i][], path[i][] == ? '+' : '-');
  35. }
  36. exflag = ;
  37. return;
  38. }
  39. if(cur != n && lv == k) return;
  40.  
  41. path[pcnt][] = id;
  42. path[pcnt++][] = ;
  43. dfs(cur+id ,lv+, id*);
  44. pcnt--;
  45.  
  46. path[pcnt][] = id;
  47. path[pcnt++][] = ;
  48. dfs(cur+id ,lv+, id*+);
  49. pcnt--;
  50.  
  51. path[pcnt][] = id;
  52. path[pcnt++][] = ;
  53. dfs(cur-id ,lv+, id*);
  54. pcnt--;
  55.  
  56. path[pcnt][] = id;
  57. path[pcnt++][] = ;
  58. dfs(cur-id ,lv+, id*+);
  59. pcnt--;
  60. }
  61.  
  62. int main() {
  63. // freopen("in", "r", stdin);
  64. int T, _ = ;
  65. scanf("%d", &T);
  66. while(T--) {
  67. scanf("%I64d %I64d", &n, &k);
  68. pcnt = ; exflag = ;
  69. printf("Case #%d:\n", _++);
  70. dfs(, , );
  71. }
  72. return ;
  73. }

DFS

  1. #include <algorithm>
  2. #include <iostream>
  3. #include <iomanip>
  4. #include <cstring>
  5. #include <climits>
  6. #include <complex>
  7. #include <fstream>
  8. #include <cassert>
  9. #include <cstdio>
  10. #include <bitset>
  11. #include <vector>
  12. #include <deque>
  13. #include <queue>
  14. #include <stack>
  15. #include <ctime>
  16. #include <set>
  17. #include <map>
  18. #include <cmath>
  19.  
  20. using namespace std;
  21.  
  22. typedef long long ll;
  23. const int maxn = ;
  24. ll n, k;
  25. ll f[maxn];
  26. ll ans[maxn];
  27. bool sub[maxn];
  28.  
  29. void init() {
  30. f[] = ;
  31. for(int i = ; i < maxn; i++) {
  32. f[i] = f[i-] * ;
  33. }
  34. }
  35.  
  36. int main() {
  37. // freopen("in", "r", stdin);
  38. int T, _ = ;
  39. init();
  40. scanf("%d", &T);
  41. while(T--) {
  42. scanf("%I64d %I64d", &n, &k);
  43. for(int i = ; i <= k; i++)
  44. ans[i] = f[i-];
  45. if(n % == ) ans[k]++;
  46. ll nn = << k;
  47. bool exflag = ;
  48. for(ll i = ; i < nn; i++) {
  49. if(exflag) break;
  50. ll cur = ;
  51. memset(sub, , sizeof(sub));
  52. for(ll j = ; j <= k; j++) {
  53. if(( << j) & i) {
  54. sub[j] = ;
  55. cur -= ans[j];
  56. }
  57. else cur += ans[j];
  58. }
  59. if(cur == n) exflag = ;
  60. }
  61. printf("Case #%d:\n", _++);
  62. for(ll i = ; i <= k; i++) {
  63. printf("%I64d ", ans[i]);
  64. if(sub[i]) printf("-\n");
  65. else printf("+\n");
  66. }
  67. }
  68. return ;
  69. }

ENUM

这个题想了很多天,想明白了其实还蛮简单的。

题目给了一棵满二叉树,按照层次遍历从左到右挨个编号1 2 3....问蛤蛤从根节点向下走,走到一个点可以加上当前节点编号也可以删掉当前节点编号。问走k层能否恰好续够n。

题目中给了一个条件:N≤2^K≤2^60

因为读题坑掉了没看到这个条件,浪费了很多时间在例如n=10 k=3的情况上。这种情况在我的搜索中是完全有结果的,但是实际上这个情况不会在题目中出现,因为8<10。

这样就好办了,我们考虑任何一个十进制数都可以表示为二进制,这个二进制表示了某一位上是否要加上对应的2的幂次。

(以上皆为口胡+脑补,正常题解在下面)

N<=2^k意味着我们总能找到第k+1个节点,使得N小于k+1节点的数值。既然如此,我们贪心地选取最左边的一条链。这样,最左边那个点必然是整层最小的。对于本题目而言,总有2^(k+1)-1≥n。

由于最左侧的链均为2的幂次,我们以前的知识中一定有这样一条规律:2^(k)-1=∑i(1,k-1)2^i。表达不清楚,举个例子:32-1=1+2+4+8+16。

我们假设整条长度为k链都是加的,那它的总和就是2^(k+1)-1,我们现在知道要求的n,那我们不需要的那部分的值为2^(k+1)-1-n。

假设这个值为x,那x也总是能表达为一个二进制数,我们只需要在这个链子上找到可以表示x的二进制数的位置,把它们标记为'-'即可。

  1. #include <algorithm>
  2. #include <iostream>
  3. #include <iomanip>
  4. #include <cstring>
  5. #include <climits>
  6. #include <complex>
  7. #include <fstream>
  8. #include <cassert>
  9. #include <cstdio>
  10. #include <bitset>
  11. #include <vector>
  12. #include <deque>
  13. #include <queue>
  14. #include <stack>
  15. #include <ctime>
  16. #include <set>
  17. #include <map>
  18. #include <cmath>
  19.  
  20. using namespace std;
  21.  
  22. typedef long long ll;
  23. const int maxn = ;
  24. ll n, k;
  25. ll f[maxn];
  26. ll ans[maxn];
  27. bool sub[maxn];
  28.  
  29. void init() {
  30. f[] = ;
  31. for(int i = ; i < maxn; i++) {
  32. f[i] = f[i-] * ;
  33. }
  34. }
  35.  
  36. int main() {
  37. // freopen("in", "r", stdin);
  38. int T, _ = ;
  39. init();
  40. scanf("%d", &T);
  41. while(T--) {
  42. scanf("%I64d %I64d", &n, &k);
  43. memset(sub, , sizeof(sub));
  44. for(int i = ; i <= k; i++)
  45. ans[i] = f[i-];
  46. ll remain = f[k] - n - ;
  47. if(n % == ) {
  48. ans[k]++;
  49. remain++;
  50. }
  51. remain >>= ;
  52. int cnt = ;
  53. while(remain) {
  54. if(remain % == ) sub[cnt] = ;
  55. remain >>= ;
  56. cnt++;
  57. }
  58. printf("Case #%d:\n", _++);
  59. for(int i = ; i <= k; i++) {
  60. printf("%I64d ", ans[i]);
  61. sub[i] ? printf("-\n") : printf("+\n");
  62. }
  63. }
  64. return ;
  65. }

[HDOJ5573]Binary Tree(找规律,贪心)的更多相关文章

  1. 找规律/贪心 Codeforces Round #310 (Div. 2) A. Case of the Zeros and Ones

    题目传送门 /* 找规律/贪心:ans = n - 01匹配的总数,水 */ #include <cstdio> #include <iostream> #include &l ...

  2. [LeetCode] 366. Find Leaves of Binary Tree 找二叉树的叶节点

    Given a binary tree, find all leaves and then remove those leaves. Then repeat the previous steps un ...

  3. [LeetCode] Find Leaves of Binary Tree 找二叉树的叶节点

    Given a binary tree, find all leaves and then remove those leaves. Then repeat the previous steps un ...

  4. LeetCode Minimum Depth of Binary Tree 找最小深度(返回最小深度)

    题意:找到离根结点最近的叶子结点的那一层(设同一层上的结点与根结点的距离相等),返回它所在的层数. 方法有: 1.递归深度搜索 2.层次搜索 方法一:递归(无优化) /** * Definition ...

  5. Codeforces Round #265 (Div. 2) C 暴力+ 找规律+ 贪心

    C. No to Palindromes! time limit per test 1 second memory limit per test 256 megabytes input standar ...

  6. hdu - 6277,2018CCPC湖南全国邀请赛B题,找规律,贪心找最优.

    题意: 给出N个小时,分配这些小时去写若干份论文,若用1小时写一份论文,该论文会被引用A次,新写一篇论文的话,全面的论文会被新论文引用一次. 找最大的H,H是指存在H遍论文,而且这些论文各被引用大于H ...

  7. UVALive - 6577 Binary Tree 递推+找规律

    题目链接: http://acm.hust.edu.cn/vjudge/problem/48421 Binary Tree Time Limit: 3000MS 问题描述 Binary Tree is ...

  8. Full Binary Tree(二叉树找规律)

    Description In computer science, a binary tree is a tree data structure in which each node has at mo ...

  9. [LeetCode] Find Mode in Binary Search Tree 找二分搜索数的众数

    Given a binary search tree (BST) with duplicates, find all the mode(s) (the most frequently occurred ...

随机推荐

  1. android的布局管理器

    理论上通过setContentView(view)能够把一个view设置到activity中,但当你有很多个view控件的时候,就需要用android的布局管理器来管理view控件了. android ...

  2. 2015 WEB前端学习路线图

    2015 WEB前端学习路线图,欢迎小伙伴补充 @落雨

  3. WinHex分析PE格式(1)

    最近在一直努力学习破解,但是发现我的基础太差了,就想学习一下PE结构.可是PE结构里的结构关系太复杂,看这老罗的WiN32汇编最后一章 翻两页又合上了..把自己的信心都搞没了.感觉自己的理解能力不行, ...

  4. 说说php取余运算(%)的那点事

    http://www.phpddt.com/php/php-take-over.html       fmod()与 % 区别   都是取余 fmod是函数 原型float fmod(float x, ...

  5. poj 1185

    上一题的升级版 dp[i][j][k] 表示第 i 行状态为 k 第i-1行状态为 j #include <cstdio> #include <cstdlib> #includ ...

  6. Python - 装饰器使用过程中的误区

    曾灵敏 - APRIL 27, 2015 装饰器基本概念 大家都知道装饰器是一个很著名的设计模式,经常被用于AOP(面向切面编程)的场景,较为经典的有插入日志,性能测试,事务处理,Web权限校验, C ...

  7. codeforces 455B A Lot of Games(博弈,字典树)

    题目 参考自博客:http://blog.csdn.net/keshuai19940722/article/details/38455269 //字典树,博弈 根据当前节点的后续来确定当前节点的状态, ...

  8. C++ 第一次上机作业

    今天完成了C++第一次上机作业,感觉比较简单. 题目: 求2个数或3个正整数中的最大数,用带有默认参数的函数实现. 对3个变量按由小到大顺序排序,要求使用变量的引用. 编写一个程序,用同一个函数名对几 ...

  9. java基础知识回顾之javaIO类---BufferedReader和BufferedWriter

    使用了装饰设计模式:此类的设计是为了提高流操作数据的效率.思想就是定义容器将数据进行临时存储,对于缓冲区对象,其实就是将这个容器进行了分装,并提供了更高效的操作方法. BufferReader: pa ...

  10. Eclipse环境下配置spket中ExtJS提示

    使用eclipse编写extjs时,一定会用到spket这个插件,spket可以单独当作ide使用,也可以当作eclipse插件使用,我这里是当作eclipse的插件使用的,下面来一步步图解说明如何配 ...