Begin
Fori:
=i+1toi+kdo{纵向填k个数}
Begin
X:
=X+j;
Result[x,y]:
=i;
End;
Dec(k);{K:
填多少个数,其规律是递减:
n,n-1,n-2,......,2,1}
Ifj=1thenj:
=-1elsej:
=1;{改变方向}
Fori:
=i+1toi+kdo{横向填k个数}
Begin
y:
=y+j;
Result[x,y]:
=i;
End;
End;
Forx:
=1tondo{输出}
Begin
Fory:
=1tondoWrite(Result[x,y]:
3);
Writeln;
End;
End.
问题2
方阵填数2
【题目】方阵填数:
在一个N×N的方阵中,填入1,2,.....N×N个数,并要求
构成如下的格式:
N=4N=5
134101341011
259112591219
68121568131820
7131416714172124
1516222325
【算法分析】
例如N=4,观察图案,是以右上→左下,或左下→右上这样的斜向来填数的。
1234这个方向可用j取1与-1来控制。
////3一共有7个斜行,每一斜行数的个数的规律1,2,3,4,3,2,1
////2例如第三斜行,其坐标变化规律:
a[1,3]->a[2,2]->a[3,1]
////1第四斜行,a[4,1]->a[3,2]->a[2,3]->a[1,4]
////坐标变化规律均是:
在上一坐标基础上加1或减1
【参考程序】
vara:
array[1..20,1..20]ofinteger;
n,x,y,i,j,k,ii:
integer;
begin
writeln('inputn:
');readln(n);{输入N}
fillchar(a,sizeof(a),0);
i:
=0;x:
=1;y:
=1;k:
=1;j:
=1;{i:
第i个数;x,y:
坐标;k:
每一斜行循环填的次数}
{j:
方向,由右上→左下,j=1;由左下→右上,j=-1}
whilei<>n*ndobegin{未填完}
forii:
=1tokdobegin{每一斜行要填k个数}
ifii>1thenbeginx:
=x+j;y:
=y-j;end;{斜行的头一个数,坐标不变}
{其他的要在原基础上根据方向j改动}
inc(i);{i存放填的数字}
a[x,y]:
=i;{填于数组相应位置}
end;
{以下确定下一斜行的首坐标,填多少个数K(即循环次数K),方向j取反}
ifj=-1theninc(y)elseinc(x);{根据上一斜行确定下一斜行的起始坐标}
j:
=-j;{方向取反}
ify>nthenbeginy:
=n;x:
=x+1;end;{调整坐标,使之不出界}
ifx>nthenbeginx:
=n;y:
=y+1;end;
ifx+y<=n+1theninc(k)elsedec(k);{确定下一斜行要填多少个数}
end;
fori:
=1tondobeginforj:
=1tondowrite(a[i,j]:
4);writeln;end;{输出}
end.
问题3
阶乘
【题目】数学上定义:
n!
=1×2×3×...×(n-1)×n(N>0)
0!
=1
若用integer型数据表示阶乘,最多可到7!
用Longint类型也只能到12!
要求输入正整数n,求n!
的精确表示
【算法分析】用数组存放结果,模拟人工计算过程,逐位去乘,注意进位情况的处理。
【参考程序1】
constmax=1000;
varn,i,j,jinwei,weishu:
integer;
result:
array[1..max]ofinteger;{result数组放结果}
begin
writeln('inputn:
');readln(n);{输入n}
fillchar(result,sizeof(result),0);
result[1]:
=1;{从1开始乘起}
jinwei:
=0;{jinwei:
进位}
weishu:
=1;{weishu:
结果的位数}
fori:
=2tondobegin{从2开始,一直乘到n}
jinwei:
=0;{进位预置为0}
forj:
=1toweishudobegin{×i,用result数组逐位去乘}
result[j]:
=result[j]*i+jinwei;{加上上一次的进位}
jinwei:
=result[j]div10;{逢10进位,生成新的进位}
result[j]:
=result[j]mod10;{result数组只放10以内的数字}
end;
whilejinwei<>0dobegin{一轮算完后,有新的进位时}
weishu:
=weishu+1;{位数加1}
result[weishu]:
=jinweimod10;{循环处理进位,直到为0}
jinwei:
=jinweidiv10;{因为进位可能不只一位数}
end;
ifweishu>maxthenbeginwriteln('error!
');halt;end;{超过预定位数,出错}
end;
write(n,'!
=');
fori:
=weishudownto1dowrite(result[i]);readln;{输出}
end.
【参考程序2】
vara:
array[1..10000]ofinteger;
b,c,d,t,x:
integer;
begin
write('inputnumber:
');
readln(x);
if(x<0)thenbeginwriteln('error!
');readln;halt;end;
fort:
=1to10000doa[t]:
=0;
d:
=1;a[1]:
=1;
forc:
=1toxdo{一直乘到x}
begin
t:
=1;b:
=0;{t:
第几位数b:
进位d:
总位数}
repeat
a[t]:
=a[t]*c+b;{数组每位均乘上c,同时加上进位}
b:
=a[t]div10;{分离出进位}
ifa[t]>=10thenif(t=d)thend:
=d+1;{假如最后一位乘时有}
{进位,则总位数加1}
a[t]:
=a[t]mod10;
inc(t);{数组下一位}
until(t>d);{直到乘完数组的每一位数字}
end;
write(x,'!
=');
fort:
=ddownto1dowrite(a[t]);{输出}
end.
问题4
乘法
【题目】求m×n的值。
(m与n的位数均不超过255位)
【算法分析】由于m与n的位数太大,所以必须用高精度运算。
与高精度阶乘不同之处在于,如何处理部分积相加的问题.
两数相乘的高精度运算,其实即是用计算机来模拟手工进行两数相乘。
试看n=811,m=98的情况:
811用m的每一位(从低位到高位)去乘n的每一位,
×98
------
6488
7299<------------注意这里如何处理相加.同理,m的百位,千位.....
-------乘n后的结果如何相加,也要处理好.
79478
【参考答案】
123456789*123456789=152********190521
1111111*111=123333321
9999999*99=989999901
987654321*987654321=975461057789971041
99999999999999999999*99999999999999999999=9999999999999999999800000000000000000001
【参考程序】
constmax=10000;
vari,j,jinwei,weishu:
integer;
n,m:
string;n_length,m_length:
integer;
result:
array[1..max]ofinteger;
begin
writeln('inputn:
');readln(n);{m,n均用字符串输入}
writeln('inputm:
');readln(m);
fillchar(result,sizeof(result),0);
n_length:
=length(n);{n_length:
被乘数n的位数}
m_length:
=length(m);{m_length:
乘数m的位数}
fori:
=1tom_lengthdobegin{用m的每个数字去乘n}
jinwei:
=0;{预置进位为0}
forj:
=1ton_lengthdobegin{因n也是大数,故要一位一位地去乘}
result[j+i-1]:
=(ord(n[n_length+1-j])-48)
*(ord(m[m_length+1-i])-48)+jinwei+result[j+i-1];
{相乘的结果放数组result,其下标j+i-1同时反应了应该加在哪个位上}
{注意要把字符串的数字转换成数值才能相乘}
jinwei:
=result[j+i-1]div10;{处理进位}
result[j+i-1]:
=result[j+i-1]mod10;
end;
weishu:
=n_length+i-1;{乘完一轮后,已有的位数}
whilejinwei<>0dobegin{处理乘完一轮后,产生的进位}
weishu:
=weishu+1;
result[weishu]:
=(jinwei+result[weishu]);
jinwei:
=(result[weishu])div10;
result[weishu]:
=(result[weishu])mod10;
end;
ifweishu>maxthenbeginwriteln('error!
');halt;end;{超过预定位数,出错}
end;
write(n,'*',m,'=');{输出}
fori:
=weishudownto1dowrite(result[i]);readln;
end.
问题5
统计单词数
【题目】读入一英文句子,单词之间用空格或逗号隔开,统计其中单词个数,并输出各个
字母出现的频率。
(句子末尾不一定用"."结束)
【算法分析】要注意连续两个空格或逗号与空格连在一起时的误判断。
例如输入以下字符串:
"abc_abc___abc,_abc___,_abc_,_."('_'代表空格)
【参考程序】
vara:
string;i,t:
byte;wor:
boolean;j:
char;
b:
array['A'..'Z']of65..90;
begin
fillchar(b,sizeof(b),0);
writeln('inputastring:
');
readln(a);t:
=1;{t:
单词数}
fori:
=1tolength(a)dobegin{逐个字符检测}
if(ord(upcase(a[i]))in[65..90])thenbegin{如果是字母}
wor:
=true;{则为某一单词的开头}
b[(upcase(a[i]))]:
=b[(upcase(a[i]))]+1;{相应字母的个数加1}
end;
ifworand((a[i]='')or(a[i]=','))then{如为","或空格,且之前为单词}
begininc(t);wor:
=false;end;{单词结束,单词数加1}
end;
ifwor=falsethendec(t);{判断行末多余的空格或","}
writeln('words:
',t);{输出单词总数}
forj:
='A'TO'Z'doifb[j]<>0thenwriteln(j,'',b[j],'');{各字母个数}
end.
问题6
【题目】一个句子,只含英文字母,单词间用空格或逗号作为分隔符。
统计句子中的单词
数,如果含有其他的字符,则只要求输出错误信息及错误类型。
含有大写字母错误类型error1
数字(0-9)错误类型error2
其他非法字符错误类型error3
如输入:
Itis12!
输出:
error123
输入:
iam,astudent
输出:
4
【参考程序】
vara:
string;ok:
boolean;error:
array[1..3]ofboolean;len,num,i,t:
integer;
begin
writeln('inputastring:
');readln(a);{a:
从键盘接收的字符串}
len:
=length(a);{求A的长度}
ok:
=true;t:
=0;{ok:
句中是否有错误的标志t:
单词总数}
fillchar(error,sizeof(error),false);
fori:
=1tolendobegin{一个一个字符取出来鉴定}
num:
=ord(a[i]);{取其序号}
ifnumin[97..122,32,44]then{如为合法字符(小写字母,空格,逗号)}
begin
ifnumin[97..122]then{如为小写字母,酌情单词数加1}
if(i=1)or((a[i-1]='')or(a[i-1]=','))thent:
=t+1;
end
else
begin
ok:
=false;{句中有错}
casenumof
65..90:
error[1]:
=true;{大写字母}
48..57:
error[2]:
=true;{数字0-9}
elseerror[3]:
=true;{其他字符}
end;
end;
end;
ifokthenwriteln('total:
',t){输出}
elsebegin
write('error');
fori:
=1to3doiferror[i]=truethenwrite(i:
2);
end;
readln;
end.