蓝桥杯-----------基础训练--贪心Huffman树、字母图形--讲解

本文介绍如何通过算法构造Huffman树并计算其总费用,同时提供了一个使用字母生成特定图形的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、贪心Huffman树

    问题描述:Huffman树在编码中有着广泛的应用。在这里,我们只关心Huffman树的构造过程。
  给出一列数{pi}={p0, p1, …, pn-1},用这列数构造Huffman树的过程如下:
  1. 找到{pi}中最小的两个数,设为pa和pb,将pa和pb从{pi}中删除掉,然后将它们的和加入到{pi}中。这个过程的费用记为pa + pb。
  2. 重复步骤1,直到{pi}中只剩下一个数。
  在上面的操作过程中,把所有的费用相加,就得到了构造Huffman树的总费用。
  本题任务:对于给定的一个数列,现在请你求出用该数列构造Huffman树的总费用。

  例如,对于数列{pi}={5, 3, 8, 2, 9},Huffman树的构造过程如下:
  1. 找到{5, 3, 8, 2, 9}中最小的两个数,分别是2和3,从{pi}中删除它们并将和5加入,得到{5, 8, 9, 5},费用为5。
  2. 找到{5, 8, 9, 5}中最小的两个数,分别是5和5,从{pi}中删除它们并将和10加入,得到{8, 9, 10},费用为10。
  3. 找到{8, 9, 10}中最小的两个数,分别是8和9,从{pi}中删除它们并将和17加入,得到{10, 17},费用为17。
  4. 找到{10, 17}中最小的两个数,分别是10和17,从{pi}中删除它们并将和27加入,得到{27},费用为27。
  5. 现在,数列中只剩下一个数27,构造过程结束,总费用为5+10+17+27=59。

    解题思想:这个题涉及到了动态的删除数据,取数据等操作。故采用ArrayList类进行解决。因为这个类的对象可以对数据进行动态的操作。首先,用该类的对象将数据添加,然后进行数据的循环,每次对现有数据进行排序(升序),然后取出前两个元素(也就是最小的两个),进行累和,存入某一变量,然后再将其添加进原数列,如此循环知道数组中只剩下一个数据完成计算。下面给出代码:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;


public class Huffman树 {
	public static int sum;
	public static void main(String[] args) {
		ArrayList<Integer> a = new ArrayList<Integer>();
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();
		for (int i = 0; i < n; i++) {
			a.add(scanner.nextInt());
		}
		for (int j = 0; j < n; j++) {
			if(a.size()==1)
			{
				System.out.println(sum);
			}
			else{
				Collections.sort(a);
				int temp = a.get(0);
				int tamp = a.get(1);
				a.remove(0);
				a.remove(0);
				sum +=(tamp+temp);			
				a.add(tamp+temp);
			}	
		}
	}

}

二、字母图形

      问题描述:利用字母可以组成一些美丽的图形,下面给出了一个例子:
          ABCDEFG
          BABCDEF
          CBABCDE
          DCBABCD
          EDCBABC
这是一个5行7列的图形,请找出这个图形的规律,并输出一个n行m列的图形。

     解题思想:首先根据输入的两个值,创建一个字符数组,存储从B开始的字符个数。之后进行行(hang)的循环,而事先进行了time的定义,其要根据变量的位置逐个增加,用法很巧妙,下面给出具体代码:

import java.util.Scanner;


public class 字母图形 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int m = sc.nextInt();                     
		char c[] = new char[m];
		int time = 0;
		for(int i = 0; i < c.length; i++)
		{ 
			c[i] = (char)('B'+i);
		}
		for(int k = 0; k < n;k++)                  	
		{
			for(int j = 0; j < c.length;j++)
			{
				if(j<time)
				{
					c[j] = (char)(c[j]+1);
				}
				if(j>=time)
				{
					c[j] = (char)(c[j]-1);
				}		
			}
			time++;
			System.out.print(c);          
			System.out.println();
		}
	}
}

后面字母图形文字部分解释较少,因为这个题的解法可以说是一种取巧的做法,可以通过读具体的代码进行理解。如有疑问可以留言。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值