收藏 分享(赏)

NOIP2007普及组复赛试题(附题解).doc

上传人:hskm5268 文档编号:7057476 上传时间:2019-05-04 格式:DOC 页数:13 大小:86.50KB
下载 相关 举报
NOIP2007普及组复赛试题(附题解).doc_第1页
第1页 / 共13页
NOIP2007普及组复赛试题(附题解).doc_第2页
第2页 / 共13页
NOIP2007普及组复赛试题(附题解).doc_第3页
第3页 / 共13页
NOIP2007普及组复赛试题(附题解).doc_第4页
第4页 / 共13页
NOIP2007普及组复赛试题(附题解).doc_第5页
第5页 / 共13页
点击查看更多>>
资源描述

1、NOIP 2007 普及组解题报告1奖学金(scholar.pasccpp)【问题描述】某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前 5 名学生发奖学金。期末,每个学生都有 3 门课的成绩:语文、数学、英语。先按总分从高到低排序,如果两个同学总分相同,再按语文成绩从高到低排序,如果两个同学总分和语文成绩都相同,那么规定学号小的同学排在前面,这样,每个学生的排序是唯一确定的。任务:先根据输入的 3 门课的成绩计算总分,然后按上述规则排序,最后按排名顺序输出前 5 名学生的学号和总分。注意,在前 5 名同学中,每个人的奖学金都不相同,因此,你必须严格按上述规则排序。例如,在某个正

2、确答案中,如果前两行的输出数据(每行输出两个数:学号、总分)是:7 2795 279这两行数据的含义是:总分最高的两个同学的学号依次是 7 号、5 号。这两名同学的总分都是 279(总分等于输入的语文、数学、英语三科成绩之和) ,但学号为 7 的学生语文成绩更高一些。如果你的前两名的输出数据是:5 2797 279则按输出错误处理,不能得分。【输入】输入文件 scholar.in 包含行 n+1 行:第 l 行为一个正整数 n,表示该校参加评选的学生人数。第 2 到年 n+l 行,每行有 3 个用空格隔开的数字,每个数字都在 0 到 100 之间。第 j行的 3 个数字依次表示学号为 j-1

3、的学生的语文、数学、英语的成绩。每个学生的学号按照输入顺序编号为 1n( 恰好是输入数据的行号减 1)。所给的数据都是正确的,不必检验。【输出】输出文件 scholar.out 共有 5 行,每行是两个用空格隔开的正整数,依次表示前 5 名学生的学号和总分。【输入输出样例 l】scholar.in scholar.out690 67 8087 66 9178 89 9188 99 7767 89 6478 89 98 6 2654 2643 2582 2441 237【输入输出样例 2】scholar.in scholar.out880 89 8988 98 7890 67 8087 66 9

4、178 89 9188 99 7767 89 6478 89 98 8 2652 2646 2641 2585 258【限制】50的数据满足:各学生的总成绩各不相同100的数据满足:6aj,1) and (ai,3=aj,3) and (ai,2=aj,2) thenbeginswap(ai,1,aj,1);swap(ai,2,aj,2);swap(ai,3,aj,3);end;for i:=1 to 5 dowriteln(ai,1, ,ai,3);close(input); 文件不要忘记关闭close(output);end.2纪念品分组(group.pasccpp)【题目描述】元旦快到了

5、,校学生会让乐乐负责新年晚会的纪念品发放工作。为使得参加晚会的同学所获得的纪念品价值相对均衡,他要把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪念品,并且每组纪念品的价格之和不能超过一个给定的整数。为了保证在尽量短的时间内发完所有纪念品,乐乐希望分组的数目最少。你的任务是写一个程序,找出所有分组方案中分组数最少的一种,输出最少的分组数目。【输入】输入文件 group.in 包含 n+2 行:第 1 行包括一个整数 w,为每组纪念品价格之和的上限。第 2 行为一个整数 n,表示购来的纪念品的总件数。第 3n+2 行每行包含一个正整数 pi(5w,s:=s+1,j:=j-1 。因为 np

6、) and (ji) do j:=j-1;if ji thenbeginai:=aj;i:=i+1;while (aih then qsort(h,j);end;beginassign(input,group.in);assign(output,group.out);reset(input);rewrite(output);readln(w);readln(n);for i:=1 to n do readln(ai);qsort(1,n); 快速排序i:=1;j:=n;s:=0;while iw thenbegins:=s+1;j:=j-1;end;end;writeln(s);close(i

7、nput);close(output);end.【深入思考】快速排序的程序比较难编,是否能有一种比较好编得排序方法呢?答案是肯定的。设 p 数组的下标为 5 至 200,每读入一个数字 x,就将 px加 1,这样数字全部读入后就是有序的了,效率甚至比快速排序还高。这样的话贪心部分也要有所改变。【参考程序 2】program a2_2(input,output);varp:array5200 of integer;x,i,w,n,j,s:integer;beginassign(input,group.in);assign(output,group.out);reset(input);rewrit

8、e(output);readln(w);readln(n);for i:=5 to 200 do pi:=0; 数组清 0for i:=1 to n do 读入数据beginreadln(x);px:=px+1;end;i:=5;j:=200;s:=0;while ij then break;if i=j then 处理 i=j 的情况if i*2=2 dobeginpi:=pi-2;s:=s+1;end;s:=s+pi;endelses:=s+pi;if i+jpj thenbegins:=s+pj;pi:=pi-pj;pj:=0;endelsebegins:=s+pi;pj:=pj-pi;

9、pi:=0;end;if i+jw then 处理 i+jw 的情况begins:=s+pj;pj:=0;end;end;writeln(s);close(input);close(output);end.3、守望者的逃离(escape.pas/c/cpp) 【问题描述】恶魔猎手尤迪安野心勃勃,他背叛了暗夜精灵,率领深藏在海底的娜迦族企图叛变。守望者在与尤迪安的交锋中遭遇了围杀,被困在一个荒芜的大岛上。为了杀死守望者,尤迪安开始对这个荒岛施咒,这座岛很快就会沉下去。到那时,岛上的所有人都会遇难。守望者的跑步速度为 17m/s,以这样的速度是无法逃离荒岛的。庆幸的是守望者拥有闪烁法术,可在 1s

10、 内移动 60m,不过每次使用闪烁法术都会消耗魔法值 10 点。守望者的魔法值恢复的速度为 4 点/s ,只有处在原地休息状态时才能恢复。现在已知守望者的魔法初值 M,他所在的初始位置与岛的出口之间的距离 S,岛沉没的时间T。你的任务写写一个程序帮助守望者计算如何在最短的时间内逃离荒岛,若不能逃出,则输出守望者在剩下的时间能走的最远距离。注意:守望者跑步、闪烁或休息活动均以秒(s)为单位,且每次活动的持续时间为整数秒。距离的单位为米(m)。【输入】在输入文件 escape.in 仅一行,包括空格隔开的三个非负整数 M,S,T。【输出】在输出文件 escape.out 包括两行:第 1 行为字符

11、串“Yes” 或“No” (区分大小写),即守望者是否能逃离荒岛。第 2 行包含一个整数。第一行为“Yes”(区分大小写)时表示守望者逃离荒岛的最短时间;第一行为“No”(区分大小写)时表示守望者能走的最远距离。【输入输出样例 1】escape.in escape.out39 200 4 No197【输入输出样例 1】escape.in escape.out36 255 10 Yes6【限制】30%的数据满足:1b then k:=a else k:=b;if k=s thenbeginwriteln(Yes); 找到最小解,提前退出writeln(i);close(input);close(

12、output);halt;end;end;for j:=10 to m dobeginbj:=max(aj+17,aj+4,aj-10+60); 动态规划if bj=s thenbeginwriteln(Yes); 找到最小解,提前退出writeln(i);close(input);close(output);halt;end;end;a:=b;end;writeln(No); 无解writeln(am);close(input);close(output);end.注:此程序两个点超时【深入思考】前面的动态规划时间复杂度太高,是否能想出更优的算法呢?思考一下,可以发现,中间的过程无非就是闪烁

13、加恢复魔法,有时再走几步,我们用 ms 数组记录,闪烁加恢复魔法可走的最大距离,再和走路比较,选出最优方案,存入 ts 数组,这样的话,时间复杂度只有 O(t),比前面的算法好得多。【参考程序 2】program a3_2(input,output);varm,s,t,ti:longint;ms:array12,0300000 of longint; ts:array0300000 of longint; beginassign(input,escape.in);assign(output,escape.out);reset(input);rewrite(output);readln(m,s,

14、t);ms2,0:=m;ts0:=0;for ti:=1 to t do 动态规划beginif ms2,ti-1=10 then 如果能使用闪烁,就是用 beginms1,ti:=ms1,ti-1+60;ms2,ti:=ms2,ti-1-10;endelsebeginms1,ti:=ms1,ti-1; 恢复魔法值ms2,ti:=ms2,ti-1+4;end;if tsti-1+17ms1,ti then tsti:=tsti-1+17 else tsti:=ms1,ti; 找出大的值if tsti=s then 如果顺利逃出,输出结果 beginwriteln(Yes);writeln(ti

15、);close(input);close(output);halt;end;end;writeln(No); 无法逃出,输出结果writeln(tst);close(input);close(output);end.此程序所有测试点全部通过4Hanoi 双塔问题(hanoi.pas/c/cpp)【问题描述】给定 A、B、C 三根足够长的细柱,在 A 柱上放有 2n 个中间有孔的圆盘,共有 n 个不同的尺寸,每个尺寸都有两个相同的圆盘,注意这两个圆盘足不加区分的(下图为 n=3 的情形) 。现要将这些圆盘移到 C 柱上,在移动过程中可放在 B 柱上暂存。要求:(1)每次只能移动一个圆盘;(2)A

16、、B 、 C 三根细柱上的圆盘都要保持上小下大的顺序;任务:设 An 为 2n 个圆盘完成上述任务所需的最少移动次数,对于输入的 n,输出 An。【输入】输入文件 hanoi.in 为一个正整数 n,表示在 A 柱上放有 2n 个圆盘。【输出】输出文件 hanoi.out 仅一行,包含一个正整数,为完成上述任务所需的最少移动次数An。【输入输出样例 1】hanoi.in hanoi.out1 2【输入输出样例 2】hanoi.in hanoi.out2 6【限制】对于 50的数据,1=2 then 减 2 的处理 a1:=a1-2elsebegina1:=a1+8;a2:=a2-1;end;i:=100;while ai=0 do i:=i-1; 计算位数for j:=i downto 1 do write(aj); 反序输出writeln;close(input);close(output);end.

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报