1、问题 E: 哈夫曼编码(coding.pas)题目描述哈夫曼编码是一种编码方式, 是可变字长编码的一种, 由 Huffman 于 1952 年提出。该方法完全依据字符出现概率来构造异字头的平均长度最短的码字, 有时称之为最佳编码,一般就叫 Huffman 编码。简单地来说,就是出现概率高的字符使用较短的编码, 反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低, 从而达到无损压缩数据的目的。现在请你模拟这样的原则对给定的一个字符串进行字母统计。输入输入文件 coding.in,只有一行,是一个字符串,由小写英文字母组成,长度不超过 255 个字符。输出输出文件 codi
2、ng.out,有若干行,每行有两部分组成:一个字母和该字母出现的频率,中间用一个空格分隔,并按频率高低排列,频率相同时则按字母的 ASC 码的先后顺序排列。样例输入soon样例输出o 2n 1s 1提示【题目分析】给出一段字符串,在字符串中出现的字符按出现次数从多到少输出,出现次数一样按字母表顺序输出。【算法分析】模拟。开一个记录字符出现次数的数组,然后按照题意输出。【参考程序】var ch:char;a:arrayazof longint;max,i:longint;beginwhile not eoln dobeginread(ch);inc(ach); /记录出现次数if achmax
3、then max:=ach; /记录出现最大出现次数end;for i:=max downto 1 do /按出现次数从大到小输出for ch:=a to z do /相同的按字母表顺序输出if ach=i then writeln(ch, ,ach); end.问题 F: 立方和(cubsum.pas)时间限制: 1 Sec 内存限制: 128 MB提交: 37 解决: 21提交状态讨论版题目描述现给出一个三位数, 先对这个三位数的各位数字的立方求和,然后再对求出的和中的各位数字的立方求和, 如此一直继续下去, 判断最后能否得到一个不再变化的固定值。如能得到一个固定值,就求出这个固定值;如果
4、不能,则输出提示信息“error” 。另外请注意,在求解过程中,若某一次求和过程中得到的值超过三位数,则取该数的低三位继续往下运算例如,对于三位数 111,则第一次计算应是 111+111+111=3,第二次计算应是 000+000+333=27,第三次计算应是 000+222+777=351,第四次计算应是 333+555+111=153,第五次计算应是 111+555+333=153,与第四次计算的结果相同,这时可不再计算,输出固定值 153。亲爱的同学,请你也来计算一下。输入输入文件 cubsum.in,只有一行,是一个三位数。输出输出文件 cubsum.out,也只有一行,如能得到一个
5、固定值,则输出这个固定值;如不能,则输出一个提示信息“error” 。样例输入111样例输出153提示输入样例 2:102输出样例 2:error【题目分析】对一个三位数字(多于三位取最低三位,少于三位添零计算)进行各个数位立方求和。判断是否最后变成一个固定的数。【算法分析】对于一个固定不变的数,则是与前一次相同,就是求立方和前相同。而没有固定值的数,则是在前面所有变化的数中出现过(当然排除前一次),因为会形成一个循环。像这样我们只要开一个记录是否出现过某个数的数组(01000)(不包括前一次),如果出现过就没有固定值。最坏情况也就 o(1000),是个常数。【参考程序】var x,y,t:l
6、ongint;a:Array010000of boolean;beginread(x);repeatt:=x; /保存一遍,因为下面 x 会变y:=sqr(x mod 10)*(x mod 10); /求立方和x:=x div 10;y:=y+sqr(x mod 10)*(x mod 10);x:=x div 10;y:=y+sqr(x mod 10)*(x mod 10);if y=t then begin writeln(y);halt;end; /求立方和与前一次相等就输出。if ay then begin writeln(error);halt;end; /出现过这个数ay:=true
7、; /这个数出现过x:=y;until false;End.问题 G: 智力大奖赛(energy.pas)时间限制: 1 Sec 内存限制: 128 MB提交: 59 解决: 34提交状态讨论版题目描述一年一度的校园智力大奖赛是小明最喜爱的活动, 今年的比赛中学校新设了一个智取能量棒的项目,小明很想参加。这个项目的比赛规则是这样的:考官在一个仪器上输入一个数,仪器屏幕上就会出现一个由许多能量棒组成的大三角形(一个大三角形有若干个小三角形组成) ,已知每根能量棒的长度都是一样的,每个小三角形由三根能量棒组成,若谁能快速答出其中小三角形的个数和能量棒的总个数,则谁就赢得了比赛, 这些能量棒作为奖励
8、也就属于他了。现在小明想邀请你和他一起参加这项比赛。输入输入文件 energy.in,只有一行,有一个整数 N,表示大三角形的层数(N45000)输出输出文件 energy.out,有二行。第一行只有一个数,表示小三角形的个数;第二行也只有一个数,表示能量棒的个数。样例输入8样例输出64108提示在 40%的数据中,1N 150在 70%的数据中,1N 30000在 100%的数据中,1N 45000【题目分析】求组成如图的边长为 n 的等边三角形要多少个小三角形和多少木棒【算法分析】小三角形个数:仔细观察,第一行只有一个三角形,最后一行有 2n-1 个三角形,而每两行之间只相差两个三角形,这
9、样我们就可以用等差数列求和的公式(1+2n-1)*n/2木棒个数:我们可以看成第 i 行有 i 个三角形,每个三角形占 3 根棒。而每行也是等差的,所以也可以用等差数列的公式(1+n)n/2*3【参考程序】var x:int64;beginread(x);writeln(1+x*2-1)*x div 2); writeln(1+x)*x div 2*3);End.问题 H: 求素数(prime.pas)时间限制: 1 Sec 内存限制: 128 MB提交: 29 解决: 13提交状态讨论版题目描述现给你 N 个 09 的数字并排成了一列,同时还给出了一个取数长度 L。规定先从第 1 个数字开始
10、从左往右连续取 L 个数字, 拼成一个长度为 L 位 (最高位为 0 的 L-1 位数除外)的数,然后从第 2 个数字开始从左往右连续取 L 个数字,这样,最后最多可以得到 N-L+1 个 L 位数。 现在请你将这些 L 位数中的素数按从小到大的顺序输出 (如果产生重复,只需输出一个) 。输入输入文件 prime.in,共有二行。第一行为 N 和 L,中间用空格隔开。 (1N100,1L7)第二行为 N 个 09 的数字,中间用空格隔开。输出输出文件 prime.out,只有一行,含全部满足条件的素数,中间用逗号隔开。样例输入10 38 9 1 0 2 3 5 4 7 6样例输出547提示【题
11、目分析】给出 n 个数,连续的取 L 个数组成一组数(开头不能为 0),求其中为素数的数,要去重复,输出从小到大,且中间以逗号隔开。【算法分析】模拟。从每个位置开始取,判断是否为素数,是素数就判断有无重复出现,无重复出现就加入数列中,然后排序,最后输出。【参考程序】var n,l,x,s,i,j:longint;b,a:array010000of longint;function pd(x:longint):boolean;var i:longint;beginif x0 then /首位字母不能为 0beginx:=0;for j:=i to i+l-1 dox:=x*10+aj;if pd(x) then /判断是否为素数beginfor j:=1 to s do /去重复if x=bj thenbreak;if x=bj then continue; s:=s+1;bs:=x;end;end;for i:=1 to s-1 do /排序for j:=i+1 to s doif bibj thenbeginx:=bi;bi:=bj;bj:=x;end;if s0 then write(b1);for i:=2 to s dowrite(,bi); /中间以逗号隔开writeln;End.【本题小结】要注意细节问题。