P1149 [NOIP2008 提高组] 火柴棒等式

简介: P1149 [NOIP2008 提高组] 火柴棒等式

d885e4868b414ec99b095dcac963568b.png

易错点:火柴也可以组成两位数、三位数等,所以需要一个函数计算数字对应的火柴棒个数。

要使用剪枝

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 10005;
int n, m;
int ans = 0; // 记录方案数
int t[4];
int a[10010] = {6, 2, 5, 5, 4, 5, 6, 3, 7, 6, 8};
int math1(int r)
{ // 计算火柴棒个数
   if (a[r] > 0)
   {
      return a[r];
   }
   else
   {
      int an = 0;
      while (r != 0)
      {
         an += a[(r % 10)];
         r = r / 10;
      }
      return an;
   }
}
void dfs(int x, int sum) // 三个位置的第几个位置
{
   if (sum > n) // 剪枝!!!
      return;
   if (x > 3)
   {
      if (t[1] + t[2] == t[3] && sum == n)
      {
         ans++;
      }
      return;
   }
   for (int i = 0; i <= 1000; i++)
   {
      t[x] = i;
      dfs(x + 1, sum + math1(i));
      t[x] = 0;
   }
}
int main()
{
 
   scanf("%d", &n);
   n = n - 4; // 先把n处理了,不然最后一个点会超时
   dfs(1, 0);
   printf("%d", ans);
}


或者使用递推进行优化:

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 10005;
int n, m;
int ans = 0; // 记录方案数
int t[4];
int a[10010] = {6, 2, 5, 5, 4, 5, 6, 3, 7, 6, 8};
void dfs(int x, int sum) // 三个位置的第几个位置
{
   if (sum > n) // 剪枝!!!
      return;
   if (x > 3)
   {
      if (t[1] + t[2] == t[3] && sum == n - 4)
      {
         ans++;
      }
      return;
   }
   for (int i = 0; i <= 1000; i++)
   {
      t[x] = i;
      dfs(x + 1, sum + a[i]);
      t[x] = 0;
   }
}
int main()
{
   scanf("%d", &n);
   n = n;
   for (int i = 10; i <= 10000; i++)
   {                                // 递推出10~1000所需的火柴棒个数
      a[i] = a[i % 10] + a[i / 10]; // 优化!
   }
   dfs(1, 0);
   printf("%d", ans);
}


相关文章
|
机器学习/深度学习 人工智能 网络架构
P1563 [NOIP2016 提高组] 玩具谜题(找规律,心要细,数学思维)
P1563 [NOIP2016 提高组] 玩具谜题(找规律,心要细,数学思维)
74 0
|
6月前
[NOIP2002]过河卒 标准递归
[NOIP2002]过河卒 标准递归
44 6
|
6月前
|
人工智能 程序员 定位技术
老程序员分享:NOIP2016天天爱跑步(树上差分)
老程序员分享:NOIP2016天天爱跑步(树上差分)
31 0
|
6月前
|
C++
【洛谷 P1042】[NOIP2003 普及组] 乒乓球 题解(模拟+向量)
`NOIP2003`普及组编程题:乒乓球比赛模拟。给定一系列球赛记录(WL序列),程序需按11分和21分制分析比分。输入含多个字符串,含W(华华得分)、L(对手得分)和E(结束标记)。输出每局比分,分制间空行间隔。样例:`WWWWWW...` → `11:0\n11:0\n1:1`(11分制)和`21:0\n2:1`(21分制)。代码使用C++,逐字符读取,当分差≥2且得分≥x时输出比分。
67 0
|
6月前
【洛谷 P1035】[NOIP2002 普及组] 级数求和 题解(循环)
**NOIP2002普及组题目:求级数$S_n=1+\frac{1}{2}+\frac{1}{3}+...+\frac{1}{n}$超过$k$的最小$n$。给定$1\leq k\leq 15$,输出满足$S_n&gt;k$的$n$。输入$1$个整数$k$,输出相应$n$。例如,输入$1$,输出$2$。代码中使用double确保精度,通过累加求和判断条件找到$n$。**
46 0
|
6月前
|
C++
【洛谷 P1047】[NOIP2005 普及组] 校门外的树 题解(位集合)
**NOIP2005普及组问题:**给定长度为$l$的马路,上面等距种植着树,需移除位于建造地铁区域的树。输入包含马路长度和区域数,以及各区域起止点,输出移树后剩余树的数量。样例输入:$l=500$, $m=3$,输出:$298$。$20\%$数据无区域重合,$1 \leq l \leq 10^4$,$1 \leq m \leq 100$。解决方案利用位集合(bitset)表示树的状态,遍历区域将树设为0,最后统计1的数量。AC代码使用C++实现。
32 0
|
6月前
|
算法
【洛谷 P1003】[NOIP2011 提高组] 铺地毯 题解(数组+贪心算法)
**NOIP2011 提高组问题:铺地毯** 在第一象限的颁奖典礼场地,有$n$张地毯按编号顺序铺设。需找出覆盖特定点$(x, y)$的最上方地毯编号。输入包括地毯坐标和点坐标,输出地毯编号或-1表示未覆盖。 样例:给定3张地毯,点$(2,2)$被第3张地毯覆盖,输出3;另一样例点$(4,5)$未被覆盖,输出-1。 $30\%$数据$n\leq2$,$50\%$数据坐标$\leq100$,$100\%$数据$n\leq10^4$,坐标$\leq10^5$。 解决方法:从下到上遍历地毯,更新覆盖点的地毯编号。 AC代码略。
61 0
|
6月前
【洛谷 P1002】[NOIP2002 普及组] 过河卒 题解(递归+记忆化搜索)
`NOIP2002`普及组的过河卒问题是一个棋盘路径计数挑战。卒从$(0,0)$出发到$(n,m)$,只能向下或向右移动,马在$(c1,c2)$固定,控制某些点。任务是计算不受马阻挡的路径数。输入是目标和马的位置,输出是路径总数。使用动态规划和记忆化搜索避免重复计算,样例输入$(6,6,3,3)$输出$6$。代码中定义了$f(x,y)$计算$(x,y)$处的路径数,利用边界条件和递推关系计算。
80 0
|
定位技术 C++
洛谷P1600 [NOIP2016 提高组] 天天爱跑步
洛谷P1600 [NOIP2016 提高组] 天天爱跑步
下一篇
DataWorks