NOI(信息学奥林匹克)联赛作为一项学科奥林匹克活动项目,这几年的初赛与复赛中都有一些跟其他科目结合类型的试题,解这种类型的试题不仅要有程序阅读与编写的能力,同时还要掌握其他相关学科的知识。这些相学科主要有数学、物理等,同时还有生活实践中的一些规则、方法等等。

这几年的初赛解答题基本上都是综合知识与能力的考查。如2002年普及组解答题中有一道是火车调度题:按一定顺序进站(要当栈来理解)问有多少种出站方式?另有一道是关于排列组合的:红球3只黄球4只,这7只球一字排开有多少种颜色组合不同的排法?提高组(高中组)解答题中一道典型的是:5本书从书架上拿下来再放上去(只有5个位置),5本书全都不放原来位置的有多少种放法?其实这就是n封信全都装错信封问题,能写出递推关系最好f(n)=(n-1)*(f(n-1)+f(n-2)) (n>2) f(1)=0,f(2)=1。如果推导不出这个公式,好在n不大,将5个数字根据规律重新排列,只要数字m不在相应的位置m就行,不过这样能不多不少地写出44这个结果的确实是要细心与周到。

再如2003年初赛提高组有一道解答题是“考试日程安排”:

有6门选修课,每人可选1到多门课。

选第1门课的人当中还有人选了第2、5、6门课;

选第2门课的人当中还有人选了第3、6门课;

选第3门课的人当中还有人选了第4、6门课;

选第4门课的人当中还有人选了第5、6门课。

假设每天每人只能考一门课,一天可以安排多门考试,那么至少要安排多少天才能使每个选了课的人都参加了自己所选课的考试?

[分析]

这是个集合问题,假设除了题中有交集外其它的没有交集,这是最少的情况(否则就是6天了),最多的是选4门课,因此要4天。至于如何安排的,本题没有要求写出,只要合理地安排就行了,每天都安排有6门课的考试,任你选择,对于任一个人来说因为他不超过4天就可以考完。

初赛的阅读程序题一般是三到四题,题目难度不大,一方面要求选手对基本语句熟悉,另一方面更是检验选手的运算技巧与解决问题的能力。2002年提高组写运行结果的第三题是这样的:

program Gxp3;

var d1,d2,x,min:real;

begin

min:=10000; x:=3;

while x<15 do

begin

d1:=sqrt(9+(x-3)*(x-3));

d2:=sqrt(36+(15-x)*(15-x));

if d1+d2<min then min:=d1+d2;

x:=x+0.001;

end;

writeln(min:10:2);

end.

读懂基本语句后发现程序是求d1+d2的最小值,控制循环的变量x是一个实数,从3一直到15,每一步增加0.001,循环共要执行12000次,每一次都有一个d1+d2的结果,不可能将这12000个结果一个个地计算出来再找出其中最小的,只有找出其中的规律才行。

观察求d1与d2的表达式,发现都是求两个数平方和的算术平方根,联想到数学知识中的求两点距离公式,用“数形结合”的方法,变量x值的变化表示x轴上从3到15这个线段,d1+d2表示x轴上的点到坐标中两个点(3,-3)与(15,6)的距离的和。如果x轴上3到15这个线段与(3,-3)与(15,6)所在的直线有交点,那么d1+d2的最小值应就是(3,-3)与(15,6)这两点的距离,因为两点之间直线距离最短。事实上它们是有交点的,且这两定点之间的距离就是((3-15)2+(-3-6)2)0.5=15,所以d1+d2可能的最小值是15。还要考虑到这个交点x的值能不能取得到,通过数学计算可以得交点的x值为7.2,这个值变量x是能够取到的,所以d1+d2最小值就是15。

程序中x:=x+0.001这个赋值语句指出了X每一步的增量,从3往后增加肯定能到7.2,如果每一步的增量改为0.1、0.2、0.3、0.4、0.6、0.7同样都能取到。如增量改为0.5时情况就不同,这时要看x=7.0 与x=7.5时哪个d1+d2的值小了。

再如2002年提高组初赛的完善程序题,第一题是求得工厂生产零件的生产计划(N天中每天应生产零件的个数),使总的费用最少,它结合了工作与生活的实践。工厂在每天的生产中需要一定数量的零件,同时也知道每天生产一个零件的单价,要能保证满足当天的需要,可以用不完,但有用不完的零件要保管费,不同的天收取的费用也不同。根据日常经验可知,某一天的费用最低并不能保证总的费用最低,总的生产计划要结合每天的需求量、每天生产零件的单价和每天保管零件的单价来确定。当某一天(第一天除外)的生产单价高于前面天数的生产单价加累计保管单价时,这一天的零件应放到前面天来生产,这样才能确保费用更低。而一旦这天的所要的零件放在前面生产的话不等于这天就没有生产零件的计划了,因为后面的天数里同样适用上面的原理。总之要一天天地检查过去才能确定最终的生产计划,难点在于如何控制这个循环检测。因为是完成程序题,重点是理解相应变量所代表的意义。而第二题则类似于现代物流管理,给出n种基本物质和K个地区对这些物质要与不要或无所谓的情况,要求指出哪些物质被使用、哪些物质不被使用。结合逻辑推理,确定要(用1描述)、不要(用-1描述)、无所谓(用0描述)之间的优先级别,“要”最高、“不要”其次、“无所谓”最低。某一物质的初始状态都为无所谓(0),当一个地区不要这种物质(-1)时可以覆盖无所谓,但不能覆盖要(1)的情况,当一个地区要这种物质时可以覆盖所有情况。根据这个规则通过循环检测最终可以得到各种物质用与不用的情况。

2003年初赛的普及组和提高组的完成程序题中都有一道“翻硬币”题。

[题意]:

有M枚硬币堆在一起,从上面开始先一次将一枚翻过来,再一次将两枚一起翻过来……最后将M枚一起翻过来,再从上面开始第一次将上面一枚翻过来,一次将上面两枚一起翻过来……直到最后还有所有M枚全部正面朝上为止。要求总的翻硬币次数。

[说明]:

这道题如果纯粹作为一个编程题,大家可能会用“模拟法”写出相关程序,设置一个标志数组,模拟这个过程,每翻一次都检查一下是否是全部正面朝上,最后输出翻的次数就可以。问题是题中给出的程序不是用这种方法,而是用的数学推导关系,也就是说要求你找出翻的总次数跟M的关系。在短的时间内找出这样的规律很难,因此此题得分率很低,几乎没有同学当场能做出。

[程序清单]:

program program42;

var m:integer;

solve(m:integer):longint;

var i,t,d:longint;

flag:boolean;

begin

if m=1 then ________(1)__________

else

begin

d:=2*m+1; t:=2; i:=1; flag:=false;

repeat

if t=1 then begin solve:=i*m; flag:=true; end

else if t=_______(2)_________ then

begin solve:=____________(3)______; flag:=true;end

else __________(4)____________;

i:=i+1;

until flag;

end;

end;

begin

read(m);

if (m>0) and (m<2000) then writeln(________(5)______);

end.

[分析]

仔细阅读和分析题意,可以能够填出第一个和第五个,因为只有一枚时要翻两次,而主程序中没有引用函数,在输出时直接引用。问题是其它三个如何填,在短时间内很难找出相关数学关系,如果有一台电脑,先写出模拟法的程序,运算出m不同数值时的对应结果,再从中找出关系还好些,初赛的性质决定了只能由人工来模拟计算机工作,找出其中的规律。

从solve函数中可以看出分成了M=1和M>1两种大的情况,在M>1的情况下,结果的不同与t有关,程序中根据t分为三种情况,其中t=1时的结果已经给出(为i*m),而另外两种情况是要求你自己完成的,其中一种情况是能够决定翻的次数的,而整个程序中没有看到对t进行处理的语句,所以要完成的任务一是:t为另一值时所确定的翻硬币的次数,任务二是:t为其它情况时对t的处理,这个处理的赋值语句肯定与m有关。仔细看一看程序,其中又引进了一个变量d,它的值是2*m+1,已有的代码中也没有用到这个变量,可以猜想给t赋值的表达式肯定是一个跟d有关的式子。

如果能结合“模拟法”程序运行得出的结果,比较结果跟i 、m的关系,就能方便地找出规律(通项公式)。

以下是m为不同值时,相关几个变量跟结果的关系:

m=3 d=7 2*m=6 重复t:=t*2 mod d运算,直到t=1或t=2*m

i 1 2 3

t 2 4 1 solve=i*m=9

m=4 d=9 2*m=8

i 1 2 3

t 2 4 8 solve=i*m-1=3*4-1=11

m=5 d=11 2*m=10

i 1 2 3 4 5

t 2 4 8 5 10 solve=i*m-1=5*5-1=24

m=6 d=13 2*m=12

i 1 2 3 4 5 6

t 2 4 8 3 6 12 solve:=i*m-1=6*6-1=35

m=7 d=15 2*m=14

i 1 2 3 4

t 2 4 8 1 solve:=i*m=4*m=28

.....

m=15 d=31 2*m=30

i 1 2 3 4 5

t 2 4 8 16 1 solve:=i*m=5*15=75

m=16 d=33 2*m=32

i 1 2 3 4 5

t 2 4 8 16 32 solve:=i*m-1=5*16-1=79

m=30 d=61 2*m=60

i 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

t 2 4 8 16 32 3 6 12 24 48 35 9 18 36 11 22 44 27 54 47 33 5 10 20 40 19 38 15 30 60

solve:=I*m-1=899

所以本题应填的结果为:

(1) solve:=2

(2) 2*m

(3) i*m-1

(4) t:=2*t mod d

(5) solve(m)

再来看看2002年NOI复赛试题,普及组的四题中有三题结合了相关的数学知识,另一题则是棋子的走法:

1、级数求和

Sn=1+1/2+1/3+……+1/n 输入K,输出最小的N,使Sn不小于K。

这题比较简单,只要根据输入的K反复执行S:=S+1/n;n:=n+1直到S>K;关键是选好变量值的类型就行了。N显然要超过整型的范围,而Sn则是实型。

2、选数

从n个整数中任选k个整数相加计算出和为素数共有多少种?

这题主要是考查你程序设计的技巧,用到的数学方面的知识是如何判断一个数是素数,不是求有多少个不同的素数,只要和为素数就行。

3、根据规则产生数,能产生多少个不同的整数;

4、过河卒

试题大意是:一只过河的小卒(位置是[0,0]),要绕过对方马(位置是[x,y])的控制,从起点到终点(位置是[m,n])有多少种走法?小卒一次只能向右或向下走一步。

这题要求选手首先能够将卒的走法数字化,马控制的八个点则限定了卒走动的范围。

大部分同学看到此题会首先会想到用回溯或递归的算法,从起点一步步地走下去,只要好走,如果走到终点走法数就增加1。这样做也没有什么不对,但是用这种算法的同学此题的30分不可能拿全,当数据量大时程序运行时间可能会超时,另外运行的结果可能会超出长整型的范围。

如果使用“分类加法”原理来解此题,就简单多了。假设卒能够到达终点(m,n),那么它只能是从上边一点或左边的一点过来,设到终点的走法数为f[m,n]、到上边点的走法数为f[m-1,n]、到左边点的走法数为f[m,n-1],根据加法原理应有:f[m,n]:=f[m-1,n]+f[m,n-1]。有了这个递推关系后程序写起来就简单多了,运行效率也比较高。

提高组试题中最为典型的是一道类似于物理的题“自由落体”:屋顶天花板上有若干个球在一条直线上,现在让它们同时自由下落,地面上的小车沿小球所在直线的方向匀速运动,求落在车上的小球数目。虽然给出了自由落体相关的物理公式,但许多同学为以什么为控制循环的基准而犯难。其实这是本次比赛中最简单的一道题,小车接到的球一定是相邻的若干个。因此,只需要算出被接到的最左与最右边的两个球即可。只要注意到以下几点,问题便好解决了:

(1) 小车只用左面和上面接球----小车左边撞上小球也算接到了小球。

(2) 注意误差处理----小球虽小也有直径且在运动着。

(3) 小车有可能一个球也接不到。

提高组其它几题如“均分纸牌”可以用模拟的方法来做,先将所有堆的张数减去世平均数;“字符变换”则是宽度搜索,如要提高速度可以用双向搜索,即从两头往中间查找;“矩形覆盖”肯定要用到几何相关基本知识。

2003年的复赛题除了要求学生对基本算法熟悉之外,同样结合了许多相关学科内容。如普及组的那道“出栈序列”统计,如果用回溯法来做,当n稍大时便会超时,如果运用组合数学的知识得到公式C(2n,n)/(n+1),纯粹变为一个数值计算问题,这样就简单多了。再如提高组的那道“逻辑推理”题,要求学生有严谨的逻辑推理能力,并将它运用到程序中去。

综上所述,信息学奥林匹克虽然是一个独立的竞赛项目,正如计算机是信息处理与解决问题的工具一样,竞赛之中的试题离不开其它学科的知识、离不开生产与生活实践,现在参加信息学奥林匹克活动可以训练思维能力、提高应用计算机解决问题的能力,同时也能促进相关学科知识水平的提高。

posted on 2011-08-05 10:39  shallyzhang  阅读(238)  评论(0)    收藏  举报