Pascal字符串的运用.ppt
第一讲 字符串的应用,导入,在历年的信息学奥赛中,字符串的操作已经是考察的热点,比如近两年来提高组的分区联赛试题中的第一题都考察到了字符串的操作,应该是大家着重掌握的内容之一。几点熟练掌握的要求1:熟练掌握从文件中读入字符串并且进行处理的技巧;2:熟练掌握字符串的各种函数和过程的运用。3:能熟练运用字符和数字之间的转化;,乒乓球,【问题背景】国际乒联现在主席沙拉拉自从上任以来就立志于推行一系列改革,以推动乒乓球运动在全球的普及。其中11分制改革引起了很大的争议,有一部分球员因为无法适应新规则只能选择退役。华华就是其中一位,他退役之后走上了乒乓球研究工作,意图弄明白11分制和21分制对选手的不同影响。在开展他的研究之前,他首先需要对他多年比赛的统计数据进行一些分析,所以需要你的帮忙。【问题描述】华华通过以下方式进行分析,首先将比赛每个球的胜负列成一张表,然后分别计算在11分制和21分制下,双方的比赛结果(截至记录末尾)。比如现在有这么一份记录,(其中W表示华华获得一分,L表示华华对手获得一分):,WWWWWWWWWWWWWWWWWWWWWWLW在11分制下,此时比赛的结果是华华第一局11比0获胜,第二局11比0获胜,正在进行第三局,当前比分1比1。而在21分制下,此时比赛结果是华华第一局21比0获胜,正在进行第二局,比分2比1。如果一局比赛刚开始,则此时比分为0比0。你的程序就是要对于一系列比赛信息的输入(WL形式),输出正确的结果。【输入格式】每个输入文件包含若干行字符串(每行至多20个字母),字符串有大写的W、L和E组成。其中E表示比赛信息结束,程序应该忽略E之后的所有内容。【输出格式】输出由两部分组成,每部分有若干行,每一行对应一局比赛的比分(按比赛信息输入顺序)。其中第一部分是11分制下的结果,第二部分是21分制下的结果,两部分之间由一个空行分隔。,算法分析,首先,对当前输入行计算11分制下每一局比赛的比分。设 a为当前局华华的得分,每输入一个W,a+1;b为当前局对方的得分,每输入一个L,b+1。若输入E或者华华的得分a或者对方得分b达到11分且双方的分数差值大于1((a11)or(b11)and(abs(a-b)1)),则输出当前局的比分a:b。请注意,如果输入的字符为E,则标志比赛结束,11分制计算完毕;否则,继续读下一个字符,计算新一局的比分。然后,对当前输入行计算21分制下每一局比赛的比分。计算方法基本如上。有所不同的是,若华华得分a或者对方得分b达到21分且双方的分数差值大于1((a21)or(b21)and(abs(a-b)1)),则输出当前局的比分a:b。按照上述方法对每一输入行计算11分制和21分制的比赛结果,直至文件读完(eof(input))为止。,assign(input,inp);reset(input);输入文件读准备 assign(output,out);rewrite(output);输出文件写准备 a:=0;b:=0;当前局双方的比分初始化 while not eof(input)do若文件未读完,则循环 begin while not eoln(input)do若当前行处理完,则11分制的比赛结束 begin read(ch);读一个字符 case ch of根据字符的种类分情形处理 E:begin若比赛结束,则输出双方比分 writeln(a,:,b);break;退出11分制的计算过程 end;E W,L:begin华华或对方得一分 if ch=Wthen inc(a)else inc(b);if(a=11)or(b=11)and(abs(a-b)1)then若有一方得分达到11分且双方的分数差值大于1,则输出双方比分 begin writeln(a,:,b);,a:=0;b:=0;新一局的比分初始化 end;then end;W,L end;case end;while readln;end;while a:=0;b:=0;新一局的比分初始化 writeln;reset(input);重新读输入行 while not eof(input)do若文件未读完且比赛未结束,则循环 begin while not eoln(input)do若当前行处理完,则21分制的比赛结束 begin read(ch);读一个字符,case ch of根据字符的种类分情形处理 E:begin若比赛结束,则输出双方比分,退出21分制的计算过程 writeln(a,:,b);break;end;EW,L:begin华华或对方得一分 if ch=Wthen inc(a)else inc(b);if(a=21)or(b=21)and(abs(a-b)1)若有一方得分达到21分且双方的分数差值大于1,则输出双方比分 then begin writeln(a,:,b);a:=0;b:=0;新一局的比分初始化 end;then end;W,L end;case end;while readln;end;whileclose(input);close(output);关闭输入文件和输出文件,关键是文件操作。如果在计算21分制的得分前,不会通过reset(input)将读头移到文件首,则会出错!,谁拿了最多奖学金,【问题描述】某校的惯例是在每学期的期末考试之后发放奖学金。发放的奖学金共有五种,获取的条件各自不同:1)院士奖学金,每人8000元,期末平均成绩高于80分(80),并且在本学期内发表1篇或1篇以上论文的学生均可获得;2)五四奖学金,每人4000元,期末平均成绩高于85分(85),并且班级评议成绩高于80分(80)的学生均可获得;3)成绩优秀奖,每人2000元,期末平均成绩高于90分(90)的学生均可获得;4)西部奖学金,每人1000元,期末平均成绩高于85分(85)的西部省份学生均可获得;5)班级贡献奖,每人850元,班级评议成绩高于80分(80)的学生干部均可获得;只要符合条件就可以得奖,每项奖学金的获奖人数没有限制,每名学生也可以同时获得多项奖学金。例如姚林的期末平均成绩是87分,班级评议成绩82分,同时他还是一位学生干部,那么他可以同时获得五四奖学金和班级贡献奖,奖金总数是4850元。现在给出若干学生的相关数据,请计算哪些同学获得的奖金总数最高(假设总有同学能满足获得奖学金的条件)。,【输入文件】输入文件scholar.in的第一行是一个整数N(1N100),表示学生的总数。接下来的N行每行是一位学生的数据,从左向右依次是姓名,期末平均成绩,班级评议成绩,是否是学生干部,是否是西部省份学生,以及发表的论文数。姓名是由大小写英文字母组成的长度不超过20的字符串(不含空格);期末平均成绩和班级评议成绩都是0到100之间的整数(包括0和100);是否是学生干部和是否是西部省份学生分别用一个字符表示,Y表示是,N表示不是;发表的论文数是0到10的整数(包括0和10)。每两个相邻数据项之间用一个空格分隔。【输出文件】输出文件scholar.out包括三行,第一行是获得最多奖金的学生的姓名,第二行是这名学生获得的奖金总数。如果有两位或两位以上的学生获得的奖金最多,输出他们之中在输入文件中出现最早的学生的姓名。第三行是这N个学生获得的奖学金的总数。,算法分析,难度分析:本题的算法是直叙式模拟,属于一道简单的数理统计题,毋需建立与问题对应的数学模型。唯一的难点就是输入数据的处理,因为每行的数据既包括字串,又包括数值,需要选手清晰地甄别和处理不同类型的数据。,用一个纪录型数组、或者多个不同类型的数组记录所有学生的信息。计算出获得最多奖金的学生并不一定要先记录下所有学生的信息,而是通过依次统计每个学生奖金的办法亦可以达到这个目的。在依次读一个学生的诸方面信息时,同一数据类型的信息用一条read语句读入,每个学生的最后一条信息用readln语句读入。我们在读完一行数据后就可统计其奖金数了,并调整目前获奖金最多的学生信息。注意,记录奖金总数的变量必须采用Longint类型(为什么)。,var name,nn:array 1.30 of char;获得最多奖金的学生姓名为name;当前学生姓名为nn n,i,j,tot,max,x,m1,m2,u:longint;b1,b2,ch:char;begin assign(input,scholar.in);reset(input);readln(n);读学生数 tot:=0;max:=0;fillchar(name,sizeof(name),);for i:=1 to n do读入每位学生的数据 begin fillchar(nn,sizeof(nn),);j:=0;读第i位学生的姓名nn repeat read(ch);if ch=then break;inc(j);nnj:=ch until false;read(m1,m2);读第i位学生的期末平均成绩和班级评议成绩、是否是学生干部和是否是西部省份学生的信息 repeat read(b1)until(b1=Y)or(b1=N);repeat read(b2)until(b2=Y)or(b2=N);,readln(u);读发表的论文数 x:=0;累计第i位学生的奖金 if(m180)and(u=1)then x:=x+8000;if(m185)and(m280)then x:=x+4000;if(m190)then x:=x+2000;if(m185)and(b2=Y)then x:=x+1000;if(m180)and(b1=Y)then x:=x+850;tot:=tot+x;累计前i位学生的奖金总数 if xmax若第i位学生的奖金最多,则调整max并记下其名字 then begin max:=x;name:=nn end then end;for close(input);关闭输入文件 assign(output,scholar.out);rewrite(output);输出文件写准备 i:=1;输出获得最多奖金的学生姓名和奖金数 while namei do begin write(namei);inc(i)end;while writeln;writeln(max);writeln(tot);输出N个学生获得的奖学金总数 close(output)关闭输出文件end.,