PASCAL竞赛辅导习题二.docx
《PASCAL竞赛辅导习题二.docx》由会员分享,可在线阅读,更多相关《PASCAL竞赛辅导习题二.docx(23页珍藏版)》请在冰豆网上搜索。
PASCAL竞赛辅导习题二
PASCAL竞赛辅导习题二
问题1
【问题】甲乙丙丁戊五个人在运动会上分获百米、二百米、跳高、跳远和铅球冠军,有
四个人猜测比赛结果:
A说:
乙获铅球冠军,丁获跳高冠军。
B说:
甲获百米冠军,戊获跳远冠军。
C说:
丙获跳远冠军,丁获二百米冠军。
D说:
乙获跳高冠军,戊获铅球冠军。
其中每个人都只说对一句,说错一句。
求五人各获哪项冠军。
【算法】用1,2,3,4,5分别代表百米、二百米、跳高、跳远和铅球5个项目,用a,b,c,d,e
分别代表五人。
如b=3表示乙获跳高冠军。
用多重循环穷举出来。
【答案】甲乙丙丁戊
12435
【参考程序】
vara,b,c,d,e:
byte;
begin
fora:
=1to5do
forb:
=1to5do
forc:
=1to5do
ford:
=1to5dobegin
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.
问题2
【问题】5家工厂的产品在一次评比中分获1,2,3,4,5,在公布结果前,已知E
厂产品肯定不是第二、三名,五厂代表猜测评比结果,
A厂的代表说:
E厂一定能获得第一名。
B厂的代表说:
我厂的产品可能获第二名。
C厂的代表说:
A厂的产品质量最次。
D厂的代表说:
C厂的产品不是最好的。
E厂的代表说:
D厂的产品会获得第一名。
公布结果后,证明只有产品获第一名和第二名的两个厂的代表猜对了。
求5个厂产品各获第几名。
【答案】ABCDE
52134
【参考程序】
vara,b,c,d,e:
byte;
begin
fora:
=1to5do
forb:
=1to5do
forc:
=1to5do
ford:
=1to5dobegin
e:
=15-a-b-c-d;
if(e<>2)and(e<>3)and(a*b*c*d*e=120)then
if(ord(e=1)+ord(b=2)+ord(a=5)+
ord(c<>1)+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((c<>1)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问题3\a
\v谁获冠军?
\a问题1\a
\v猜测产品质量评奖\a问题2\a
问题3
【问题】有A、B、C、D四名偷窃嫌疑犯,其中一人是小偷,审问中,A说:
“我
不是小偷”,B说:
“C是小偷”,C说:
“小偷肯定是D”,D说:
“C
在冤枉人”,有三人说真话,一人说假话,问到底谁是小偷?
【参考程序】
varthief:
char;
begin
forthief:
='A'to'D'do
iford(thief<>'A')+ord(thief='C')+ord(thief='D')+
ord(thief<>'D')=3thenwriteln('TheThiefis:
',thief);
end.
问题4
字母塔
【问题】输出由字母组成的“字母塔”。
例如:
输入C,则输出:
A
ABA
ABCBA
ABCDCBA
【参考程序】
vari,zimu,j,k:
char;
begin
repeat
writeln('inputachar:
');
readln(zimu);
zimu:
=upcase(zimu);
until(zimu>='A')and(zimu<='Z');
fori:
='A'tozimudobegin
write('':
(ord(zimu)-ord(i))+1);{留空格}
forj:
='A'toidowrite(j);{顺序写字母}
forj:
=pred(i)downto'A'dowrite(j);{逆序写字母}
if(ord(i)-64)mod25=0thenreadln{如超一页,要暂停分页显示}
elsewriteln;
end;
end.
问题5
进制1
【题目】键盘输入一个十进制的整数,及确定进制n,把这个数转换成相应的n进制输出。
(其中2〈=n〈=16)
例如:
输入10,n=3则输出(10)10=(101)3
【参考程序】
vari,j,m,n:
longint;
a:
array[1..100]ofbyte;{用数组存放求出的余数}
begin
writeln('inputm,n');
fillchar(a,sizeof(a),0);
readln(m,n);
write(m);
i:
=0;
repeat
i:
=i+1;
a[i]:
=mmodn;
m:
=mdivn;
untilm=0;
write('=(');
forj:
=idownto1do
ifa[j]>9thenwrite(chr(a[j]+55)){如果大于9,用字母输出}
elsewrite(a[j]);
writeln(')',n);readln;
end.
问题6
进制2
【题目】把n进制的数化回十进制表示
如(10101)2=(21)10
【参考程序】
varcf,s,i,j,n:
longint;
m:
string[20];
a:
array[1..20]ofbyte;
begin
writeln('inputm,n');
fillchar(a,sizeof(a),0);
readln(m,n);{用字符串接收要转换的数}
fori:
=1tolength(m)dobegin{把字符串换成数字,注意字母时的情况}
if(m[i]<='9')and(m[i]>='0')thena[i]:
=ord(m[i])-48;
if(upcase(m[i])<='F')and(upcase(m[i])>='A')then
a[i]:
=ord(upcase(m[i]))-55;
ifa[i]>=nthenbeginwriteln('Error,Invaildm!
');halt;end;
{如果含有不在n进制内的字符,则判为出错。
如2进制的数,则不应
出现诸如10102,110031210等情况}
end;
cf:
=1;s:
=a[length(m)];{cf:
乘方}
fori:
=length(m)-1downto1dobegin{从低位向高位,逐步转换}
cf:
=cf*n;{s记录得出来的数}
s:
=s+a[i]*cf;
end;
writeln('(',m,')',n,'=',s);
readln;
end.
问题7
进制3
【题目】任意进制间的互化。
把n进制的M转化成k进制表示
如m=ffn=16k=2
则有(ff)16=(11111111)2
【参考程序】
vars,n,k:
longint;m:
string[20];
a:
array[1..100]ofbyte;
procedurefirst(m:
string;n:
integer);{把数m化成十进制}
varcf,i,j:
longint;
begin
fori:
=1tolength(m)dobegin
if(m[i]<='9')and(m[i]>='0')thena[i]:
=ord(m[i])-48;
if(upcase(m[i])<='F')and(upcase(m[i])>='A')then
a[i]:
=ord(upcase(m[i]))-55;
ifa[i]>=nthenbeginwriteln('Error,Invaildm!
');halt;end;
end;
cf:
=1;s:
=a[length(m)];
fori:
=length(m)-1downto1dobegin
cf:
=cf*n;
s:
=s+a[i]*cf;
end;
write('(',m,')',n);write('=(',s,')10');
end;
proceduresecond(m,n:
longint);{把十进制的数化成k进制}
vari,j:
longint;
begin
i:
=0;
repeat
i:
=i+1;
a[i]:
=mmodn;
m:
=mdivn;
untilm=0;
write('=(');
forj:
=idownto1do
ifa[j]>9thenwrite(chr(a[j]+55))
elsewrite(a[j]);
writeln(')',n);readln;
end;
begin
fillchar(a,sizeof(a),0);
writeln('inputm,n,k:
');{m:
数,n:
原先进制,k:
化成什么进制}
readln(m,n,k);
first(m,n);{把n进制的m化成十进制数S}
second(s,k);{把S化成k进制}
end.
问题8
钞票换硬币
【题目】把一元钞票换成一分、二分、五分硬币(每种至少一枚),有哪些种换法?
【答案】461种
【参考程序】
vari,j,k,total:
integer;
begin
total:
=0;{总数设为0}
fori:
=1to99do{i:
二分硬币最多99枚}
forj:
=1to49do{j:
二分硬币最多49枚}
fork:
=1to19do{k:
五分硬币最多19枚}
ifi*1+j*2+k*5=100thenbegin
writeln(i:
3,j:
3,k:
3);
inc(total);{总数加1}
end;
writeln(total);
readln;
end.
问题9
百钱买百鸡
【题目】一只公鸡值5元,一只母鸡值3元,3只小鸡值1元,现用一百元要买一百只鸡,
问有什么方案?
【答案】四种方案:
公鸡母鸡小鸡
①02575
②41878
③81181
④12484
【参考程序】
问题10
分书问题
【题目】有A、B、C、D、E五本书,要分给张、王、刘、 ┏━┯━┯━┯━┯━┯━┓
赵、钱五位同学,每人只能选一本,事先让每人把自┃│A│B│C│D│E┃
己喜爱的书法填于右表,编程找出让每人都满意的方┠─┼─┼─┼─┼─┼─┨
案。
┃张│││√│√│┃
┠─┼─┼─┼─┼─┼─┨
【答案】四种方案┃王│√│√│││√┃
张王刘赵钱┠─┼─┼─┼─┼─┼─┨
①CABDE┃刘││√│√││┃
②DACBE┠─┼─┼─┼─┼─┼─┨
③DBCAE┃赵│√│√││√│┃
④DECAB┠─┼─┼─┼─┼─┼─┨
┃钱││√│││√┃
┗━┷━┷━┷━┷━┷━┛
【参考程序】
varz,w,l,zh,q,total:
byte;
procedureoutput;
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;
forz:
=3to4do
forw:
=1to5do
if(w<>3)and(w<>4)then
forl:
=2to3do
forzh:
=1to4do
ifzh<>3then
forq:
=2to5do
if(q<>3)and(q<>4)thenbegin
ifz+w+l+zh+q=15then
ifz*w*l*zh*q=120thenoutput;
end;
write(total);
end.
问题11
筛选法
【题目】统计楼梯级数。
一步跨二级多一级,一步跨三级多二级,如果分别用四、五、六、
七去除级数分别余三、三、五、五。
要求用筛选法求这个楼梯最少有多少级。
【答案】383级
【参考程序1】
vara:
array[1..1000]ofboolean;
b:
array[1..10]ofinteger;
k,i,n,t:
integer;
begin
fori:
=2to1000doa[i]:
=true;
n:
=2;t:
=1;
b[1]:
=1;b[2]:
=2;b[3]:
=3;b[4]:
=3;b[5]:
=5;b[6]:
=5;{表示各种跨法的余数}
repeat
fork:
=2to1000do{每一次筛选都从头到尾}
ifa[k]=truethen
if(k-b[t])modn<>0thena[k]:
=false;{把不可能情况筛去}
n:
=n+1;t:
=t+1;{下一种可能}
untiln>7;{一共筛7次}
fori:
=2to1000doifa[i]=truethenbeginwrite(i:
5);readln;halt;end;
end.
【参考程序2】
constmax=1000;
vari:
integer;a:
array[1..max]of0..7;
begin
fillchar(a,sizeof(a),0);
i:
=1;repeati:
=i+2;a[i]:
=a[i]+1;untili>max;{一步跨二级}
i:
=2;repeati:
=i+3;a[i]:
=a[i]+1;untili>max;{三}
i:
=3;repeati:
=i+4;a[i]:
=a[i]+1;untili>max;{四}
i:
=3;repeati:
=i+5;a[i]:
=a[i]+1;untili>max;{五}
i:
=5;repeati:
=i+6;a[i]:
=a[i]+1;untili>max;{六}
i:
=5;repeati:
=i+7;a[i]:
=a[i]+1;untili>max;{七}
fori:
=1tomaxdoif(a[i]=6)thenbeginwriteln(i);halt;end;
end.{跨了6次的梯级便为所求}
【参考程序3】程序3是程序2的精简,具有比程序2更好的通用性。
constmax=1000;
b:
array[2..7]ofbyte=(1,2,3,3,5,5);{各种跨法剩余的级数}
vari,j:
integer;a:
array[1..max]of0..7;
begin
fillchar(a,sizeof(a),0);{置初值}
forj:
=2to7dobegin{从2级到7级}
i:
=b[j];
repeat
i:
=i+j;{每一次可能跨到的级数}
a[i]:
=a[i]+1;{某级跨到一次,记录一次}
untili>max;{从头跨到尾}
end;
fori:
=1tomaxdo
if(a[i]=6)then{跨了6次的梯级便为所求}
beginwriteln(i);halt;end;{找到第一个满足条件的便可结束程序}
end.
问题12
求最大公约数
【题目】求两个正整数的最大公约数
【算法】用辗转相除法(参看P40例3)
【参考程序】
varm,n,r,t:
integer;
begin
writeln('inputm,n');
readln(m,n);
if(n<=0)or(m<=0)thenbeginwriteln('error!
');halt;end;
ifm=m;m:
=n;n:
=t;end;{大数放m,小数放n}
r:
=mmodn;{r:
余数}
whiler<>0dobegin
m:
=n;
n:
=r;
r:
=mmodn;
end;
writeln('yushu:
',n);
end.
问题13
素数2
【问题】任给一个自然数n,求出这个自然数不同因数的个数。
例如n=6时,因为1,2,3,6这四个数均是6的因数,故输出为total=4。
【算法】类似判断素数的方法。
如果发现n有一个≤sqr(n)的因数,必然同时有一个≥sqr(n)的因数。
例如:
6有一个因数2,则必有另一因数3。
因为2*3=6
【参考程序】
varn,nums,k,i:
longint;
begin
repeat
writeln('inputn:
');
readln(n);
ifn<=0thenwriteln('N>0!
!
');
untiln>0;
k:
=trunc(sqrt(n));
nums:
=2;
fori:
=2tokdo
ifnmodi=0thennums:
=nums+2;
ifn=sqr(k)thendec(nums);
writeln('nums:
',nums);
end.
问题14
万年历
【题目】输入年、月、日,求这一天是星期几。
【参考程序1】
【算法提要】求出这一天离公元1年的元旦有多少天days,然后对7求余
const
first=1;{公元1年为基准}
first_week=1;{公元1年的元旦为星期一}
yue:
array[1..12]of1..31=(31,28,31,30,31,30,31,31,30,31,30,31);
week_:
array[0..6]ofstring[20]=('Sunday','Monday','Tuesday','Wedsday',
'Thursday','Friday','Saturday');
var
days,week,year,month,date,i,years:
longint;
begin
writeln('year:
');readln(year);
writeln('month');readln(month);
writeln('date');readln(date);
years:
=0;days:
=0;
fori:
=firsttoyear-1do
if(imod400=0)or(imod4=0)and(imod100<>0)then
beginyears:
=years+1;end;{注意处理闰年的情况}
days:
=(year-first)*365+years;{离基准年过了多少天}
fori:
=1tomonth-1dodays:
=days+yue[i];{本年过了多少个月}
fori:
=1todatedodays:
=days+1;{本月过了多少天}
if((yearmod400=0)or(yearmod4=0)and(yearmod100<>0))
and(month>3)thendays:
=days+1;{如果本年为闰年,且月份超2月,
还要考虑加1}
week:
=((days-1)mod7+first_week)mod7;{求星期数}
writeln('itis',week_[week]);
readln;
end.
【参考程序2】用公式法:
days:
=trunc((year-1)*(1+1/4-1/100+1/400)+c)
用求出的days对7求余数。
其中c为该天离该年元旦的天数
const
first=1;
first_week=1;
yue:
array[1..12]of1..31=(31,28,31,30,31,30,31,31,30,31,30,31);
week_:
array[0..6]ofstring[20]=('Sunday','Monday','Tuesday','Wedsday',
'Thursday','Friday','Saturday');
var
days,week,year,month,date,i:
longint;
begin
writeln('year:
');readln(year);
writeln('month');readln(month);
writeln('date');readln(date);
days:
=0;
fori:
=1tomonth-1dodays:
=days+yue[i];
fori:
=1todatedodays:
=days+1;
if((yearmod400=0)or(yearmod4=0)and(yearmod100<>0))
and(month>3)thendays:
=days+1;
days:
=trunc((year-1)*(1+1/4-1/100+1/400)+days);
week:
=daysmod7;
writeln('itis',week_[week]);
readln;
end.
问题15
猴子选大王
【问题】n只猴子选大王,选举办法如下:
从头到尾1,2,3报数,凡报3的退出,
余下的从尾到头1,2,3报