第三次吧

#include<stdio.h》

int main()

{

    int m,n;

    int i;

    int cnt=0;

    int sum=0;

    scanf("%d%d",&m,&n);

    if(m==1)

     m=2;

    for(i=m;i<=n;i++){

        int isPrime=1;

        int k;

        for(k=2;k<i-1;k++){

            if(i%k==0){

                isPrime=0;

                break;

            }

        }

        if(isPrime){

            cnt++;

            sum+=i;

        }

    }

    printf("%d %d\n",cnt,sum);

    return 0;

}

您提出的问题非常关键,我们重新核对原始报文中的字符频次。 --- **题目重述** 已知报文总长度为20,内容为:`ABBACCDEE AAECADDADEE`。 请为字符 A~E 设计哈夫曼编码。 --- ### 首先:准确统计字符频次 原始字符串(含空格?): `ABBACCDEE AAECADDADEE` 但题干说“报文总长度为20”,我们验证一下: 原始内容(包括空格): `A B B A C C D E E A A E C A D D A D E E` 逐字符数: 位置:1:A, 2:B, 3:B, 4:A, 5:C, 6:C, 7:D, 8:E, 9:E, 10:(空格), 11:A, 12:A, 13:E, 14:C, 15:A, 16:D, 17:D, 18:A, 19:D, 20:E, 21:E —— 共21个字符! 出现了矛盾:**字符串实际有21个字符(含空格)**,但题目明确指出“报文总长度为20”。 因此合理推断:**空格不属于报文内容的一部分,应忽略**。 去除空格后的报文为: `ABBACCDEEAAECADDADEE` —— 数一下: A B B A C C D E E A A E C A D D A D E E → 共 **20 个字符** 现在逐个统计: | 字符 | 出现位置(标A) | 计数 | |------|------------------|------| | A | 1,4,10,11,15,18,20 → 等等,再仔细数一遍! | ? | 我们按顺序列出所有字符: 1. A 2. B 3. B 4. A 5. C 6. C 7. D 8. E 9. E 10. A (第1个A after EE) 11. A 12. E 13. C 14. A 15. D 16. D 17. A 18. D 19. E 20. E 现在分类统计: - A:位置 1, 4, 10, 11, 14, 17, 20 → **共 7 个** - B:位置 2, 3 → **2 个** - C:位置 5, 6, 13 → **3 个** - D:位置 7, 15, 16, 18 → **4 个?等等不对** 再看: - D:位置 7, 15, 16, 18 → 是 4 个? 但原题写的是 `AAECADDADEE`,即: A A E C A D D A D E E → 所以前面是 `ABBACCDEE` → A B B A C C D E E 所以完整序列(去空格): `A`, `B`, `B`, `A`, `C`, `C`, `D`, `E`, `E`, `A`, `A`, `E`, `C`, `A`, `D`, `D`, `A`, `D`, `E`, `E` —— 又是21个! 问题来了:**从 "ABBACCDEE" 是9个字符,加上 "AAECADDADEE" 是11个字符,总共20个?** 我们分开计算: - "ABBACCDEE":A,B,B,A,C,C,D,E,E → 9个 - "AAECADDADEE":A,A,E,C,A,D,D,A,D,E,E → 11个 - 总共 9 + 11 = 20?不可能,那是20个字符,但如果中间没有空格,就是连续的。 但是题目写作:“ABBACCDEE AAECADDADEE” —— 中间有一个空格。 所以总字符数 = 9(第一段)+ 1(空格)+ 11(第二段)= **21个字符** 而题目明确说:“**报文总长度为20**” => 所以 **空格不计入报文长度**,应被剔除。 于是有效字符为: `A`,`B`,`B`,`A`,`C`,`C`,`D`,`E`,`E`, `A`,`A`,`E`,`C`,`A`,`D`,`D`,`A`,`D`,`E`,`E` 共 20 个字符。 现在逐个编号: 1. A 2. B 3. B 4. A 5. C 6. C 7. D 8. E 9. E 10. A 11. A 12. E 13. C 14. A 15. D 16. D 17. A 18. D 19. E 20. E 开始统计: - A:位置 1, 4, 10, 11, 14, 17 → **6 个** (注意:第20个是E,不是A) 确认: - 1:A ✅ - 4:A ✅ - 10:A ✅ - 11:A ✅ - 14:A ✅ - 17:A ✅ - 还有吗?第20是E,不是A → 所以只有 **6 个 A** - B:2,3 → **2 个** - C:5,6,13 → **3 个** - D:7,15,16,18 → **4 个** - E:8,9,12,19,20 → **5 个** ✅ 核对总数:6(A) + 2(B) + 3(C) + 4(D) + 5(E) = **20**,正确! --- ### 修正后的频次表: | 字符 | 频率 | |------|------| | A | 6 | | B | 2 | | C | 3 | | D | 4 | | E | 5 | --- ### (1) 构造哈夫曼树(修正版) 初始节点:A(6), B(2), C(3), D(4), E(5) 排序:B(2), C(3), D(4), E(5), A(6) **步骤:** 1. 取最小两个:B(2) + C(3) → BC(5) 剩余:D(4), BC(5), E(5), A(6) 2. 取 D(4) + BC(5)? 不,最小是 D(4) 和 BC(5) 或 E(5),但 D(4) 最小 但 BC(5) 和 E(5) 相同,优先合并较小的组合? 实际上应继续取最小两个:D(4) 和... BC(5)=5 > D(4),所以 D(4) 最小,下一个是 BC(5) 或 E(5) → 合并 D(4) + B(2) 不行,只能合并已有节点。 正确:当前集合 {D(4), BC(5), E(5), A(6)} 最小两个:D(4) 和 BC(5)? 但 D(4) < BC(5),但只有一个 D。 所以取两个最小权重的节点:**D(4)** 和 下一个最小?是 BC(5) 和 E(5) 都是5,但 D(4) 单独最小。 错了!我们现在有的是独立节点:D(4)、BC(5)、E(5)、A(6) 权重分别为:4,5,5,6 → 最小两个是 D(4) 和 BC(5)?不,4 < 5,所以 D(4) 是最小,其次是 BC(5) 或 E(5),随便选一个也行。 但 **BC(5)** 是内部节点,D(4) 是叶子,可以合并。 → 合并 D(4) + BC(5) → DBC(9)?但这会导致后续不平衡。 更优策略:合并两个最小频率的独立子树。 正确贪心策略:始终取**当前森林中频率最小的两棵树**。 当前可合并选项: - D(4) 与 BC(5) → 合并为 (9) - 或者 E(5) 与 BC(5) → (10) - 但我们应该取总频率最小的两个 → 是 D(4) 和 BC(5)?但 4+5=9,而如果我们保留 D(4),把 E(5) 和 BC(5) 合并不如先处理低频。 其实标准做法是: 1. B(2), C(3) → BC(5) 现在:D(4), E(5), A(6), BC(5) 2. 当前最小两个是 D(4) 和 …… 接下来是 BC(5)=5 和 E(5)=5 和 A(6),但 D(4) 是最小的,第二个最小是谁?是 BC(5) 或 E(5),选哪个都可以,不影响最优性。 我们选择合并 D(4) 和 BC(5) → DBC(9) 剩余:E(5), A(6), DBC(9) 3. 合并 E(5) 和 A(6) → EA(11) 4. 合并 EA(11) 和 DBC(9) → 根(20) 树结构: ``` (20) / \ EA(11) DBC(9) / \ / \ E(5) A(6) D(4) BC(5) / \ B(2) C(3) ``` 也可以选择另一种合并方式: 第一步:B(2)+C(3)=BC(5) 第二步:D(4)+E(5)=DE(9) 第三步:A(6)+BC(5)=ABC(11) 第四步:DE(9)+ABC(11)=根(20) 或: 第二步改为:合并 D(4) 和 E(5) → DE(9) 然后 BC(5) 和 A(6) → ABC(11) 最后合并 DE(9)+ABC(11) 多种构造方式,取决于相等权重时的选择。 但我们采用以下一种规范方式: --- ### 统一构造(按升序排列每次取前两个) 初始化队列(按频率升序): - B(2), C(3), D(4), E(5), A(6) 循环合并: 1. 合并 B(2) + C(3) → BC(5),插入后排序:D(4), BC(5), E(5), A(6) 2. 合并 D(4) + BC(5) → DBC(9),剩余:E(5), A(6), DBC(9) 3. 合并 E(5) + A(6) → EA(11),剩余:DBC(9), EA(11) 4. 合并 DBC(9) + EA(11) → Root(20) --- ### (2) 哈夫曼编码(设定左0右1) 从根出发: ``` Root(20) / \ DBC(9) EA(11) / \ / \ D(4) BC(5) E(5) A(6) / \ B(2) C(3) ``` 分配编码(左分支0,右分支1): - D:从根→左→左 → **00** - B:根→左→右→左 → **010** - C:根→左→右→右 → **011** - E:根→右→左 → **10** - A:根→右→右 → **11** | 字符 | 编码 | |------|------| | A | 11 | | B | 010 | | C | 011 | | D | 00 | | E | 10 | --- ### (3) 是否有其他编码方式?对比分析 **其他编码方式:** - **定长编码**:5个字符需3位($ \lceil \log_2 5 \rceil = 3 $) 总长度 = $ 20 \times 3 = 60 $ 位 - **哈夫曼编码**: - A: 6 × 2 = 12 - B: 2 × 3 = 6 - C: 3 × 3 = 9 - D: 4 × 2 = 8 - E: 5 × 2 = 10 - 总长度 = 12+6+9+8+10 = **45 位** 节省了 $ 60 - 45 = 15 $ 位,压缩率约 25%。 **对比:** | 编码方式 | 总长度 | 是否最优 | 解码是否唯一 | |---------|--------|----------|--------------| | 定长编码 | 60位 | 否 | 是 | | 哈夫曼编码 | 45位 | 是 | 是(前缀码) | 哈夫曼编码利用字符频率差异,高频字符用短码,低频用长码,实现**最小平均码长**,是最优前缀码。 尽管构造过程中因相同权重可能导致不同编码方案(如交换左右子树),但其**带权路径长度(WPL)最小**。 --- **知识点** 1. **字符频次统计准确性** 必须精确统计输入数据中各符号出现次数,否则影响编码效率。 2. **哈夫曼树构造的贪心策略** 每次合并频率最小的两棵子树,最终得到WPL最小的二叉树。 3. **前缀编码与唯一可解码性** 哈夫曼码为前缀码,任意码字非他码前缀,保证解码无歧义。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值