一、贪心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();
}
}
}
后面字母图形文字部分解释较少,因为这个题的解法可以说是一种取巧的做法,可以通过读具体的代码进行理解。如有疑问可以留言。