1、PASCAL竞赛辅导习题二PASCAL竞赛辅导习题二问题【问题】甲乙丙丁戊五个人在运动会上分获百米、二百米、跳高、跳远和铅球冠军,有 四个人猜测比赛结果: 说:乙获铅球冠军,丁获跳高冠军。 说:甲获百米冠军,戊获跳远冠军。 说:丙获跳远冠军,丁获二百米冠军。 说:乙获跳高冠军,戊获铅球冠军。 其中每个人都只说对一句,说错一句。求五人各获哪项冠军。【算法】用1,2,3,4,5分别代表百米、二百米、跳高、跳远和铅球个项目,用a,b,c,d,e 分别代表五人。如b=3 表示乙获跳高冠军。用多重循环穷举出来。【答案】甲 乙 丙 丁 戊 【参考程序】 var a,b,c,d,e:byte; begin
2、for a:=1 to 5 do for b:=1 to 5 do for c:=1 to 5 do for d:=1 to 5 do begin e:=15-a-b-c-d; if (ord(b=5)+ord(d=3)=1) and (ord(a=1)+ord(e=4)=1) and (ord(c=4)+ord(d=2)=1) and (ord(b=3)+ord(e=5)=1) and (a*b*c*d*e=120) then writeln(a:,a,b:,b,c:,c,d:,d,e:,e); end; end.问题【问题】家工厂的产品在一次评比中分获,在公布结果前,已知 厂产品肯定不是第
3、二、三名,五厂代表猜测评比结果, 厂的代表说:厂一定能获得第一名。 厂的代表说:我厂的产品可能获第二名。 厂的代表说:厂的产品质量最次。 厂的代表说:厂的产品不是最好的。 厂的代表说:厂的产品会获得第一名。 公布结果后,证明只有产品获第一名和第二名的两个厂的代表猜对了。 求个厂产品各获第几名。【答案】 【参考程序】 var a,b,c,d,e:byte; begin for a:=1 to 5 do for b:=1 to 5 do for c:=1 to 5 do for d:=1 to 5 do begin e:=15-a-b-c-d; if (e2) and (e3) and (a*b*
4、c*d*e=120) then if(ord(e=1)+ord(b=2)+ord(a=5)+ ord(c1)+ ord(d=1)=2) and (ord(e=1) and (a=1) or (a=2)+ ord(b=2) and (b=1) or (b=2)+ ord(a=5) and (c=1) or (c=2)+ ord(c1) and (d=1) or (d=2)+ ord(d=1) and (e=1) or (e=2) =2) then writeln(a:,a, b:,b, c:,c, d:,d, e:,e); end; end.问题3逻辑判断v谁是小偷a问题av谁获冠军?a问题av
5、猜测产品质量评奖a问题a问题【问题】有、四名偷窃嫌疑犯,其中一人是小偷,审问中,说:“我 不是小偷”,说:“是小偷”,说:“小偷肯定是”,说:“ 在冤枉人”,有三人说真话,一人说假话,问到底谁是小偷?【参考程序】 var thief:char; begin for thief:=A to D do if ord(thiefA)+ord(thief=C)+ord(thief=D)+ ord(thiefD)=3 then writeln(The Thief is : ,thief); end.问题4字母塔【问题】输出由字母组成的“字母塔”。例如:输入,则输出: A ABA ABCBA ABCDCB
6、A【参考程序】 var i,zimu,j,k:char; begin repeat writeln(input a char:); readln(zimu); zimu:=upcase(zimu); until (zimu=A) and (zimu9 then write(chr(aj+55) 如果大于,用字母输出 else write(aj); writeln(),n);readln; end.问题6进制2【题目】把n进制的数化回十进制表示 如 (10101)2=(21)10【参考程序】 var cf,s,i,j,n:longint; m:string20; a:array1.20 of b
7、yte; begin writeln(input m,n); fillchar(a,sizeof(a),0); readln(m,n); 用字符串接收要转换的数 for i:=1 to length(m) do begin 把字符串换成数字,注意字母时的情况 if (mi=0) then ai:=ord(mi)-48; if (upcase(mi)=A) then ai:=ord(upcase(mi)-55; if ai=n then begin writeln(Error, Invaild m !);halt;end; 如果含有不在n进制内的字符,则判为出错。如进制的数,则不应 出现诸如10
8、102,110031210等情况 end; cf:=1; s:=alength(m); cf:乘方 for i:=length(m)-1 downto 1 do begin 从低位向高位,逐步转换 cf:=cf*n; s记录得出来的数 s:=s+ai*cf; end; writeln(,m,),n,=,s); readln; end.问题7进制3【题目】任意进制间的互化。 把n进制的转化成k进制表示 如m=ff n=16 k=2 则有 (ff)16=(11111111)2【参考程序】 var s,n,k:longint;m:string20; a:array 1.100 of byte; pr
9、ocedure first(m:string;n:integer); 把数m化成十进制 var cf,i,j:longint; begin for i:=1 to length(m) do begin if (mi=0) then ai:=ord(mi)-48; if (upcase(mi)=A) then ai:=ord(upcase(mi)-55; if ai=n then begin writeln(Error, Invaild m !);halt;end; end; cf:=1; s:=alength(m); for i:=length(m)-1 downto 1 do begin c
10、f:=cf*n; s:=s+ai*cf; end; write(,m,),n);write(=(,s,)10); end; procedure second(m,n:longint); 把十进制的数化成k进制 var i,j:longint; begin i:=0; repeat i:=i+1; ai:= m mod n; m:=m div n; until m=0; write(=(); for j:=i downto 1 do if aj9 then write(chr(aj+55) else write(aj); writeln(),n);readln; end; begin fillc
11、har(a,sizeof(a),0); writeln(input m,n,k:); m:数, n:原先进制, k:化成什么进制 readln(m,n,k); first(m,n); 把n进制的m化成十进制数 second(s,k); 把化成k进制 end.问题8钞票换硬币【题目】把一元钞票换成一分、二分、五分硬币(每种至少一枚),有哪些种换法?【答案】461种【参考程序】 var i,j,k,total:integer; begin total:=0; 总数设为 for i:=1 to 99 do i:二分硬币最多99枚 for j:=1 to 49 do j:二分硬币最多49枚 for k
12、:=1 to 19 do k:五分硬币最多19枚 if i*1+j*2+k*5=100 then begin writeln(i:3,j:3,k:3); inc(total); 总数加 end; writeln(total); readln; end.问题9百钱买百鸡【题目】一只公鸡值元,一只母鸡值元,只小鸡值元,现用一百元要买一百只鸡, 问有什么方案?【答案】四种方案: 公鸡 母鸡 小鸡 【参考程序】问题10分书问题【题目】有、五本书,要分给张、王、刘、 赵、钱五位同学,每人只能选一本, 事先让每人把自 己喜爱的书法填于右表,编程找出让每人都满意的方 案。 张 【答案】四种方案 王 张 王
13、刘 赵 钱 刘 赵 钱 【参考程序】 var z,w,l,zh,q,total:byte; procedure output; begin writeln(zhang:,chr(z+64); writeln(wang:,chr(w+64); writeln(liu :,chr(l+64); writeln(zhao:,chr(zh+64); writeln(qian:,chr(q+64); writeln; inc(total); end; begin total:=0; for z:=3 to 4 do for w:=1 to 5 do if (w3) and (w4) then for l
14、:=2 to 3 do for zh:=1 to 4 do if zh3 then for q:=2 to 5 do if (q3) and (q4) then begin if z+w+l+zh+q=15 then if z*w*l*zh*q=120 then output; end; write(total); end.问题11筛选法【题目】统计楼梯级数。一步跨二级多一级,一步跨三级多二级,如果分别用四、五、六、 七去除级数分别余三、三、五、五。要求用筛选法求这个楼梯最少有多少级。【答案】级【参考程序】var a:array1.1000of boolean; b:array1.10 of
15、integer; k,i,n,t:integer;beginfor i:=2 to 1000 do ai:=true;n:=2;t:=1;b1:=1;b2:=2;b3:=3;b4:=3;b5:=5;b6:=5; 表示各种跨法的余数repeat for k:=2 to 1000 do 每一次筛选都从头到尾 if ak=true then if (k-bt)mod n0 then ak:=false; 把不可能情况筛去 n:=n+1;t:=t+1;下一种可能until n7; 一共筛7次for i:=2 to 1000 do if ai=true then begin write(i:5);rea
16、dln; halt;end;end.【参考程序】const max=1000;var i:integer;a:array1.maxof 0.7;begin fillchar(a,sizeof(a),0); i:=1; repeat i:=i+2; ai:=ai+1; until imax; 一步跨二级 i:=2; repeat i:=i+3; ai:=ai+1; until imax; 三 i:=3; repeat i:=i+4; ai:=ai+1; until imax; 四 i:=3; repeat i:=i+5; ai:=ai+1; until imax; 五 i:=5; repeat
17、i:=i+6; ai:=ai+1; until imax; 六 i:=5; repeat i:=i+7; ai:=ai+1; until imax; 七 for i:=1 to max do if (ai=6) then begin writeln(i);halt;end;end. 跨了6次的梯级便为所求【参考程序】 程序是程序的精简,具有比程序更好的通用性。const max=1000; b:array2.7 of byte =(1,2,3,3,5,5); 各种跨法剩余的级数var i,j:integer;a:array1.maxof 0.7;begin fillchar(a,sizeof(
18、a),0); 置初值 for j:=2 to 7 do begin 从2级到7级 i:=bj; repeat i:=i+j; 每一次可能跨到的级数 ai:=ai+1; 某级跨到一次,记录一次 until imax; 从头跨到尾 end; for i:=1 to max do if (ai=6) then 跨了6次的梯级便为所求 begin writeln(i);halt;end; 找到第一个满足条件的便可结束程序end.问题12求最大公约数【题目】求两个正整数的最大公约数【算法】用辗转相除法 (参看40例3)【参考程序】 var m,n,r,t:integer; begin writeln(i
19、nput m,n); readln(m,n); if (n=0) or (m=0) then begin writeln(error!);halt;end; if mn then begin t:=m;m:=n;n:=t;end; 大数放m,小数放n r:=m mod n; r:余数 while r0 do begin m:=n; n:=r; r:=m mod n; end; writeln(yu shu:,n); end.问题13素数【问题】任给一个自然数n,求出这个自然数不同因数的个数。 例如 n=6时,因为1,2,3,6这四个数均是的因数,故输出为total=。【算法】类似判断素数的方法
20、。 如果发现n有一个sqr()的因数,必然同时有一个sqr(n)的因数。 例如:有一个因数,则必有另一因数。因为*36【参考程序】 var n,nums,k,i:longint; begin repeat writeln(input n:); readln(n); if n0!); until n0; k:=trunc(sqrt(n); nums:=2; for i:=2 to k do if n mod i=0 then nums:=nums+2; if n=sqr(k) then dec(nums); writeln(nums:,nums); end.问题14万年历【题目】输入年、月、日,
21、求这一天是星期几。【参考程序】【算法提要】求出这一天离公元年的元旦有多少天days,然后对7求余 const first=1; 公元年为基准 first_week=1; 公元年的元旦为星期一 yue:array1.12 of 1.31=(31,28,31,30,31,30,31,31,30,31,30,31); week_:array0.6 of string20 =(Sunday,Monday,Tuesday,Wedsday, Thursday,Friday,Saturday); var days,week,year,month,date,i,years:longint; begin wri
22、teln(year:);readln(year); writeln(month);readln(month); writeln(date);readln(date); years:=0; days:=0; for i:=first to year-1 do if (i mod 400=0) or (i mod 4=0) and (i mod 1000) then begin years:=years+1;end; 注意处理闰年的情况 days:=(year-first)*365+years; 离基准年过了多少天 for i:=1 to month-1 do days:=days+yuei; 本
23、年过了多少个月 for i:=1 to date do days:=days+1; 本月过了多少天 if (year mod 400=0) or (year mod 4=0) and (year mod 1000) and (month3) then days:=days+1; 如果本年为闰年,且月份超月, 还要考虑加 week:=(days-1) mod 7 +first_week ) mod 7; 求星期数 writeln(it is ,week_week); readln; end.【参考程序】 用公式法: days:=trunc(year-1)*(1+1/4-1/100+1/400)+
24、c) 用求出的days对求余数。其中c为该天离该年元旦的天数 const first=1; first_week=1; yue:array1.12 of 1.31=(31,28,31,30,31,30,31,31,30,31,30,31); week_:array0.6 of string20 =(Sunday,Monday,Tuesday,Wedsday, Thursday,Friday,Saturday); var days,week,year,month,date,i:longint; begin writeln(year:);readln(year); writeln(month);r
25、eadln(month); writeln(date);readln(date); days:=0; for i:=1 to month-1 do days:=days+yuei; for i:=1 to date do days:=days+1; if (year mod 400=0) or (year mod 4=0) and (year mod 1000) and (month3) then days:=days+1; days:=trunc(year-1)*(1+1/4-1/100+1/400)+days); week:=days mod 7; writeln(it is ,week_week); readln; end.问题15猴子选大王【问题】n只猴子选大王,选举办法如下:从头到尾,报数,凡报的退出, 余下的从尾到头,报
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1