2011-2013年湖南理工学院程序设计试题

更新时间:2024-01-14 22:35:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

湖南理工学院2011程序设计竞赛参考答案 1. 解不等式

设n为正整数,求n至少为多大,满足以下不等式 a<1+1/(1+1/2)+...+1/(1+1/2+...+1/n

输入正整数a,输出满足不等式的n的最小值。 输入a=100 输出: 输入a=2011 输出: (1) 应用一重循环求解

// 解不等式: a<1+1/(1+1/2)+...+1/(1+1/2+...+1/n) #include #include void main() { long a,i; double ts,s;

printf(\请输入a: \i=0;ts=0;s=0; while(s<=a) { i=i+1;

ts=ts+(double)1/i; // ts为各项的分母 s=s+1/ts; }

printf(\满足不等式的正整数n至少为: %ld \\n\}

输入a: 100,输出满足不等式的正整数n至少为: 566 输入a: 2011,输出满足不等式的正整数n至少为: 18622 (2) 应用二重循环求解

// 解不等式: a<1+1/(1+1/2)+...+1/(1+1/2+...+1/n) #include #include void main() { long a,i,k; double ts,s;

printf(\请输入a: \i=0;ts=0;s=0; while(s<=a) { i=i+1;ts=0;

for(k=1;k<=i;k++)

ts=ts+(double)1/k; // ts为各项的分母 s=s+1/ts; }

printf(\满足不等式的正整数n至少为: %ld \\n\}

注:当a非常大时,程序运行时间可能比较长(时间复杂度为O(n))。 (3) 验证程序

// 求和: s=1+1/(1+1/2)+...+1/(1+1/2+...+1/n) #include #include void main() { long i,n; double ts,s;

printf(\请输入n: \ts=0;s=0;

for(i=1;i<=n;i++)

{ ts=ts+(double)1/i; // ts为各项的分母 s=s+1/ts; }

printf(\}

验证:

请输入n: 565, s=99.87895 请输入n: 566, s=100.02353 请输入n: 18621, s=2010.99170 请输入n: 18622, s=2011.08777 (4)不等式拓广

// 解不等式: 2011<1+1/(1+1/2)+...+1/(1+1/2+...+1/n)<2012 #include #include void main() { long c,d,i; double ts,s; i=0;ts=0;s=0; while(s<=2011) { i=i+1;

ts=ts+(double)1/i; // ts为各项的分母 s=s+1/ts; } c=i; 2

while(s<=2012) { i=i+1;

ts=ts+(double)1/i; // ts为各项的分母 s=s+1/ts; }

d=i-1; // 注意:上限为i-1,而不是i

printf(\满足不等式的正整数n: %ld≤n≤%ld \\n\}

满足不等式的正整数n: 18622≤n≤18631

2. 统计

试求恰含有k个数字7且不能被7整除的7位整数的个数s。 输入k,输出s。 k=1, 输出: k=3, 输出: (1) 设计要点

设置t循环穷举所有7位数。

为了检测7位数t含有多少个数字7,每个7位整数t赋给d(以保持t不变),然后通过7次求余先后分离出t的7个数字c,if(c==7) f++;用变量f统计数字7的个数。 例如f=2,说明整数t中恰含2个数字7。

据f==k && k%7>0检测t恰含有k个数字7且不能被7整除,s作相应统计。 (2)程序设计

// 恰含k个数字7且不能被7整除的7位整数的个数 #include void main() { int j,c,k,f; long d,s,t;

printf(\请输入整数k(1<=k<=6): \s=0;

for(t=1000000;t<=9999999;t++) // 枚举每一个7位数 { d=t; f=0;

for(j=1;j<=7;j++) { c=d; d=d/10;

if(c==7) f++; // 统计7位整数中各数字的个数 }

if(f==k && t%7>0) // 统计含k个数字7且不能被7整除数的个数 s++; }

printf(\恰含%d个数字7且不能被7整除的7位整数的个数s=%ld \\n\(3)程序运行示例

请输入整数k(1<=k<=6): 1

恰含1个数字7且不能被7整除的7位整数的个数s=2884960 请输入整数k(1<=k<=6): 3

恰含3个数字7且不能被7整除的7位整数的个数s=184316 (4) 问题拓广

// 恰含k个数字7且不能被7整除的m位整数的个数 #include void main() { int j,c,k,f,m; long d,s,t,x;

printf(\请输入整数m(2<=m<=9): \printf(\请输入整数k(1<=k

for(j=2;j<=m;j++) x=x*10; // x=10^(m-1) 为最小的m位数

s=0;

for(t=x;t<=10*x-1;t++) // 枚举每一个m位数 { d=t; f=0;

for(j=1;j<=m;j++) { c=d; d=d/10;

if(c==7) f++; // 统计m位整数中各数字的个数

} if(f==k && t%7>0) // 统计含k个数字7且不能被7整除数的个数 s++; }

printf(\恰含%d个数字7且不能被7整除的%d位整数的个数s=%ld \\n\}

3. 求最值

设整数a的所有因数(含1与本身)之和为s,定义 p(a)=s/a 为整数a的因数比。 例如,6的因数有1,2,3,6,s=1+2+3+6=12,p(6)=12/6=2。

试求指定区间[x,y]中整数的因数比的最大值(精确到小数点后4位)。 输入x,y, 输出最大因数比的整数a及其因数比p(a)。 输入x=1000,y=2011, 输出: 输入x=10000,y=100000, 输出: (1)设计要点

设置a循环穷举区间[x,y]中的所有整数。可在整数范围内操作。

为了求整数a的因数和s,显然1与a是因数。设置k(2——sqrt(a))循环枚举,如果k是a的因数,则a/k也是a的因数,约定k≤a/k。

如果a=b*b,显然k=b,a/k=b,此时k=a/k。而因数b只有一个,所以此时必须从和s中减去一个b,这样处理以避免重复。 通过比较求s/a的最大值s1/a1。 (2)程序设计

// 求[x,y]范围内整数的因数比最大值 #include #include void main()

{ long a,s,a1,s1,b,k,x,y;

printf(\请输入区间x,y: \a1=1;s1=1;

for(a=x;a<=y;a++) // 枚举区间内的所有整数a {s=1+a;b=(long)sqrt(a);

for(k=2;k<=b;k++) // 试商寻求a的因数k

if(a%k==0)s=s+k+a/k; // k与a/k是a的因数,求和

if(a==b*b) s=s-b; // 如果a=b^2,因k=a/k,需去掉重复因数b if((double)s/a>(double)s1/a1)

{a1=a;s1=s; } // 比较求s/a的最大值s1/a1 }

printf(\整数%ld的因数比最大:%.4f\\n\}

(3)程序运行示例

求区间[x,y]中整数的因数比最大值. 请输入整数x,y:1000,2011 整数1680的因数比最大:3.5429

求区间[x,y]中整数的因数比最大值. 请输入整数x,y:10000,100000 整数55440的因数比最大:4.1870

(4) 试商求因数的范围选择

// 求[x,y]范围内整数的因数比最大值 #include #include void main()

{ long a,s,a1,s1,b,k,x,y;

printf(\请输入区间x,y: \a1=1;s1=1;

for(a=x;a<=y;a++) // 枚举区间内的所有整数a {s=1+a;b=a/2;

for(k=2;k<=b;k++) // 试商寻求a的因数k if(a%k==0)

s=s+k; // k是a的因数,求和 if((double)s/a>(double)s1/a1)

{a1=a;s1=s; } // 比较求s/a的最大值s1/a1 }

printf(\整数%ld的因数比最大:%.4f\\n\}

2说明:试商从2至a/2, 其时间复杂度为O(n);而试商从2至sqrt(a),其时间复杂度为O(nn)。 当参数y非常大时,程序运行时间太长,可能得不到相应的解。 (5)应用双精度变量且带验证的程序设计

设置a循环穷举区间[x,y]中的所有整数。可在双精范围内操作。

为了求整数a的因数和s,显然1与a是因数。设置k(2——sqrt(a))循环枚举,如果k是a的因数,则a/k也是a的因数,约定k≤a/k。

如果a=b*b,显然k=b,a/k=b,此时k=a/k。而因数b只有一个,所以此时必须从和s中减去一个b,这样处理以避免重复。

设置max存储因数比最大值。枚举区间内每一整数a,求得其因数和s。通过s/a与max比较求取因数比最大值。

对比较所得因数比最大的整数,通过试商输出其因数和式。 // 求[x,y]范围内整数的因数比最大值(带验证) #include #include void main()

{ double a,s,a1,s1,s2,b,k,t,x,y,max=0;

printf(\求区间[x,y]中整数的因数比最大值.\printf(\请输入整数x,y:\scanf(\

for(a=x;a<=y;a++) // 枚举区间内的所有整数a

{s=1+a;b=sqrt(a);

for(k=2;k<=b;k++) // 试商寻求a的因数k if(fmod(a,k)==0)

s=s+k+a/k; // k与a/k是a的因数,求和

if(a==b*b) s=s-b; // 如果a=b^2,去掉重复因数b t=s/a; if(max

{max=t;a1=a;s1=s;} }

printf(\整数%.0f的因数比最大:%.4f \\n\printf(\的因数和为:%.0f \\n\printf(\输出其因数和式 for(s2=1+a1,k=2;k<=a1/2;k++) if(fmod(a1,k)==0)

{ s2+=k;printf(\printf(\

if(s1==s2) printf(\完成验证!\\n\}

程序运行示例:

求区间[x,y]中整数的因数比最大值. 请输入整数x,y:1000,2011 整数1680的因数比最大:3.5429 1680的因数和为:5952

1+2+3+4+5+6+7+8+10+12+14+15+16+20+21+24+28+30+35+40+42+48+56+60+70+80+84+105 +112+120+140+168+210+240+280+336+420+560+840+1680 =5952. 完成验证! 求区间[x,y]中整数的因数比最大值. 请输入整数x,y:10000,100000 整数55440的因数比最大:4.1870 55440的因数和为:232128

1+2+3+4+5+6+7+8+9+10+11+12+14+15+16+18+20+21+22+24+28+30+33+35+36+40+42+44+4 5+48+55+56+60+63+66+70+72+77+80+84+88+90+99+105+110+112+120+126+132+140+144+154+

165+168+176+180+198+210+220+231+240+252+264+280+308+315+330+336+360+385+396+420+

440+462+495+504+528+560+616+630+660+693+720+770+792+840+880+924+990+1008+1155+12

32+1260+1320+1386+1540+1584+1680+1848+1980+2310+2520+2640+2772+3080+3465+3696+39

60+4620+5040+5544+6160+6930+7920+9240+11088+13860+18480+27720+55440 =232128. 完成验证!

(6)变通:求k完全数 设整数a的所有因数(含1与本身)之和为s,若s为a的k倍,即s=k*a(k为指定的正整数),则称a为k完全数。

例如,6的因数有1,2,3,6,s=1+2+3+6=12=2*6,称6为2完全数。 试求指定区间[x,y]中整数的所有k完全数。

输入x,y,k, 输出区间[x,y]中整数的所有k完全数。

输入x=100,y=1000,k=3 输出:

输入x=10000,y=100000,k=4 输出: 1)设计要点

为了求整数a的因数和s,显然1与a是因数。设置j(2——sqrt(a))循环枚举,如果j是a的因数,

则a/j也是a的因数。

如果a=b*b,显然j=b,a/j=b,此时j=a/j。而因数b只有一个,所以此时必须从和s中减去一个b,这样处理以避免重复。 若s=k*a,则输出。 2)程序设计

// 求[x,y]范围内整数的k完全数 #include #include void main()

{ long a,s,b,j,x,y,k;

printf(\请输入整数x,y:\printf(\请输入整数k: \for(a=x;a<=y;a++) // 枚举区间内的所有整数a {s=1+a;b=sqrt(a);

for(j=2;j<=b;j++) // 试商寻求a的因数k if(a%j==0)

s=s+j+a/j; // k与a/k是a的因数,求和

if(a==b*b) s=s-b; // 如果a=b^2,去掉重复因数b if(s==k*a) printf(\} }

3)程序运行示例

请输入整数x,y:100,1000 请输入整数k: 3 120 672

请输入整数x,y:10000,100000 请输入整数k: 4 30240, 32760

4. 完美综合运算式

以下含加、减、乘、除的综合运算式的右边为一位非负整数f,请把数字0,1,2,...,9这10个数字中不同于数字 f 的 9个数字不能重复填入式左边的9个□中,?(约定数字“1”、“0”不出现在式左边的一位数中,“0”不为首位),使得该完美综合运算式成立 □□×□+□□□÷□-□□=f

例如,当f=5时,18*4+203/7-96=5 就是一个满足条件的完美综合运算式,数字0,1,2,...,9这10个数字在式中各出现一次。

输入整数f(0≤f≤9),输出对应的所有综合运算式。 输入整数f=6,输出对应的所有综合运算式。 输入整数f=8,输出对应的所有综合运算式。 (1)设计要点

设式左的5个整数从左至右分别为a,b,c,d,e,即 a*b+c/d-e=f,其中c为三位整数,a,e为二位整数,b,d为大于1的一位整数。

设置a,b,c,d循环,对每一组a,b,c,d,计算e=a*b+c/d-f。若其中的c/d非整数,或所得e非二位数,则返回。

然后分别对6个整数进行数字分离,设置g数组对6个整数分离的共9个数字进行统计,g(x)即为数字x(0—9)的个数。

若某一g(x)不为1,不满足数字0,1,...,9这10个数字都出现一次且只出现一次,标记t=1. 若所有g(x)全为1,满足数字0,1,...,9这10个数字都出现一次且只出现一次,保持标记t=0, 则输出所得的完美综合运算式。 设置n统计解的个数。 (2)程序设计

// 完美综合运算式设计1 #include void main()

{int x,y,t,k,a,b,c,d,e,f,n=0; int m[6],g[10];

printf(\请输入f: \for(a=10;a<=98;a++) for(b=2;b<=9;b++)

for(c=102;c<=987;c++) // 设置a,b,c,d穷举 for(d=2;d<=9;d++) { x=c/d;e=a*b+x-f;

if(c!=x*d || e>100) continue;

m[1]=a;m[2]=b;m[3]=c;m[4]=d;m[5]=e; for(x=0;x<=9;x++) g[x]=0;g[f]=1; for(k=1;k<=5;k++) { y=m[k]; while(y>0)

{ x=y;g[x]=g[x]+1;

y=y/10; // 分离数字f数组统计 } }

for(t=0,x=0;x<=9;x++) if(g[x]!=1)

{t=1; break;} // 检验数字0--9各只出现一次 if(t==0) // 输出一个解,用n统计个数 {n++;

printf(\} }

printf(\}

(3)程序运行示例 请输入f: 6

1: 18*4+203/7-95=6 2: 25*3+140/7-89=6 3: 37*2+108/4-95=6 请输入f: 8

1: 13*5+240/6-97=8 2: 16*3+270/5-94=8

(4)完美综合运算式设计2

由 a*b+c/d-e=f 推得 c=(f+e-a*b)*d // 完美综合运算式设计2 #include void main()

{int x,y,t,k,a,b,c,d,e,f,n=0; int m[6],g[10]; for(f=0;f<=9;f++) for(a=10;a<=98;a++) for(b=2;b<=9;b++)

for(d=2;d<=9;d++) // 设置a,b,d,e,f穷举 for(e=10;e<=98;e++) { c=(f+e-a*b)*d;

if(c<100 || c>=1000) continue;

m[1]=a;m[2]=b;m[3]=c;m[4]=d;m[5]=e; for(x=0;x<=9;x++) g[x]=0;g[f]=1; for(k=1;k<=5;k++) { y=m[k]; while(y>0)

{ x=y;g[x]=g[x]+1;

y=y/10; // 分离数字f数组统计 } }

for(t=0,x=0;x<=9;x++) if(g[x]!=1)

{t=1; break;} // 检验数字0--9各只出现一次 if(t==0) // 输出一个解,用n统计个数 {n++;

printf(\} }

printf(\}

5. 素数幻方

试寻求9个素数,构造一个3阶素数幻方:该方阵中3行、3列与两对角线上的3个素数之和均等于给定的整数(幻和)s。

输入s,输出所有幻和为s的3阶素数幻方。 输入789,输出所有3阶素数幻方。 输入2019,输出所有3阶素数幻方。

(1)数学建模

设素数幻方正中间数为n,幻和(即每行,每列与每对角线之和)为s。?注意到 (中间一行)+(中间一列)+2*(两对角线)=6s (上下行)+(左右列)=4s 两式相减即得

6n=2s → n=s/3 (1)

这意味着凡含n的行或列及对角线的三数中,除n之外的另两数与n相差等距。为此,设3阶素数幻方为: n-x n+w n-y

n+z n n-z (2) n+y n-w n+x

同时设方阵的两对角线的三数为大数在下(即x,y>0),下面一行三数为大数在右(即x>y)。这样约定是避免重复统计解。

显见,上述3×3方阵的中间一行,中间一列与两对角线上三数之和均为3n。?要使左右两列,上下两行的三数之和也为3n,当且仅当 x=y+z

w=x+y (x>y) (3)

同时易知9个素数中不能有偶素数2,因而x,y,z,w都只能是正偶数。 (2)程序设计

对于键盘输入的整数s, 如果存在幻和为s的素数幻方,则s应为中间素数的3倍。若s不是3的整数倍,则对输入的s,输出“无解!”而退出。

设置a数组,数组元素清“0”。通过试商判别,寻找出[3,s]中的所有素数k,并标注a[k]=1,为以后的判断提供依据。 设n=s/3,若a[n]==0,知n不是素数,显然不存在幻和为s的素数幻,显示“无解!”后退出。设幻方中的素数下界为c,上界为d。 显然c=3,注意到d+n+c=s,则d≤2n-3。 注意到 n-y≥3,(n+y)+n+(n-y)=s 得 2n+y=s-(n-y)≤s-3 即 y≤s-2n-3=n-3

在[2,n-3]中枚举y,在[y+2,n-3]枚举x,并按上述(3)式得z,w:

若出现x=2y,将导致z=y,方阵中出现两对相同的数,显然应予排除。 显然n-w是9个数中最小的,n+w是9个数中最大的。若n-wd,已超出[c,d]界限,应予以排除。

检测方阵中其他8个数n-x,n+w,n-y,n+z,n-z,n+y,n-w,n+x是否同时为素数,引用变量t1,t2,t1*t2为8个数的标记之积。若t1*t2=0,即8个数中存在非素数,返回。否则,已找到一个三阶素数幻方解,按方阵格式输出并用变量m统计基本解的个数。 这样处理,能较快的找出所有解,既无重复,也没有遗漏。 (3)程序清单

// 指定幻和的三阶素数幻方 #include #include void main()

{int c,d,j,k,n,t,t1,t2,s,w,x,y,z,m; int a[3000];

{

for(j=i+1;j<=9;j++);for(p=0;p<=n-1;p++);if(p<=n-1-q)c[k][p]=i;elsec[k][p]=j;;k++;;/*for(j=0;j<81*(n-1);;for(i=0;i

for(p=0;p<=n-1;p++) {

if(p<=n-1-q) c[k][p]=i; else c[k][p]=j; } k++; } } } }

/*for(j=0;j<81*(n-1);j++) //输出所有n位数的双码二部数! {

for(i=0;i

cout<

湖南理工学院2013程序设计竞赛 1 求代数和

设和式s(n)= 1×2×3-2×3×4+….+(-1)n+1×n×(n+1)×(n+2) (和式中共n项,各项符号“+”与“-”相间) 输入整数n(1≤n<3000),计算并输出和s(n)。 数据测试: (1) n=100 (2) n=2013

参考解答:

设置双精度实型变量s实施累加。

在j(1——n)循环实施代数和累加即可。 程序设计:

// s(n)= 1×2×3-2×3×4+?+-n×(n+1)×(n+2) #include void main()

{ int j,n; double s;

printf(\请输入整数n: \

scanf(\

s=0; // s清零 for(j=1;j<=n;j++)

if(j%2==1) s+=j*(j+1)*(j+2); // 求和 else s-=j*(j+1)*(j+2);

printf(\输出和s }

请输入整数n: 100 s(100)=-522750

请输入整数n: 2013 s(2013)=4087630512 2 表的列号

在EXCEL工作表中最多有256列,从第1列开始至右列号依次为A,B,C,……,Y,Z;AA,AB,……..,AZ;BA,BB,……..,BZ;CA,CB,CC,?。 试换算并输出第n列的列号。 输入正整数n(n≤256),输出相应的列号。例如,输入60,输出第60列的列号BH。测试数据: (1) n=100 (2) n=200 参考解答:

设置字符数组:d[27]=\显然d*0+=’A’,d*25+=’Z’。

对输入的整数n,计算x=(n-1)/26为第1个字符序号,当x=0时无第1个字符;计算y=(n-1)&为第2个字符序号. 程序设计: // 表的列号 #include void main() { int n,x,y;

char d[27]=\printf(\请输入整数n: \scanf(\

x=(n-1)/26;y=(n-1)&;

if(x==0) printf(\前26列只输出一个字母 else printf(\}

// 表的列号改进(省字符串) #include void main() { int x,y; long n;

printf(\请输入整数n: \scanf(\if(n<=26)

{printf(\前26列只输出一个字母 return;

} else

{ x=n/26;y=n&; if(y==0) {x=x-1;y=26;}

printf(\} }

数据测试: n=100: CV n=200: GR

实训1. 长列序号转换代码 引申:列号n在长整形不限

列号n在长整形不限,从第1列开始至右列代码依次为A,B,C,?,Y,Z;AA,AB,?,ZZ;AAA,AAB,?,ZZZ;AAAA,AAAB,?。 试换算并输出第n列的列代码。 测试数据:n=2013; n=20132014 实训2. 表的列代码与序号互换 测试数据:

请输入正整数n: 123456789012345,该列代码为:_________ 请输入列代码(大写字母串):ZYXWABCDEF, 该列序号为:__________ 3 小数求和

设和式s(n)= 1.7+2.77+3.777+…+(n+0.77…..7) (s(n)为n项之和,其中第k项整数部分为k,小数点后有k个数字7)输入整数n(1≤n<3000),计算并输出和s(n)(四舍五入精确到小数点后6位)。数据测试: (1) n=100 (2) n=2013 参考解答:

设置双精实变量s实施累加。

在j(1——n)循环中枚举和式的每一项,设当前项的小数部分为t,其后一项显然为 t=t/10+0.7; 每一项在t的基础上加整数部分j即可。 设计设计: // 求s(n)

#include void main()

{ int j,n; double t,s;

printf(\请输入整数n: \scanf(\t=s=0; // t,s清零 for(j=1;j<=n;j++)

{ t=t/10+0.7; // t为第j项小数部分 s+=t+j; // 求和s }

printf(\输出和s }

另简解:

注意到整数部分相加为n*(n+1)/2;

设d9=0.9+0.99+?+0.99?9=n-0.11?1=n-0.1111111(取7位即可) 而d7=d9/9*7;因而有 // 求s(n)简化 #include void main() { int n; double s;

printf(\请输入整数n: \scanf(\

s=n*(n+1)/2+(n-0.1111111)*7/9; // 求和s printf(\输出和s }

请输入整数n: 100 s(100)=5127.691358 请输入整数n: 2013

s(2013)=2028656.580247

实训3. 同码小数之和

整数部分为零小数部分各位数字相同的小数称为同码小数,例如0.3,0.33,0.333,?,是同数码3的小数,记这些小数的前5项之和0.3+0.33+0.333+0.3333+0.33333为s(3,5),记前5 项的加权和0.3+2×0.33+3×0.333+4×0.3333+5×0.33333为w(3,5),一般地记 s(d,n)= 0.d+0.dd+0.ddd+?+0.dd?d

w(d,n)= 0.d+2×0.dd+3×0.ddd+?+n×0.dd?d

(两和式为n项之和,其中第k项小数点后有k个数字d,加权和第k项的权系数为k)依次输入整数d(1≤d≤9),n(1≤n<10000),计算并输出和s(d,n)与w(d,n)(四舍五入精确到小数点后6位)。

测试数据: d=7,n=2014; d=8,n=2013 实训4. 同码小数统计 对于给定的同码小数的和

s(d,n)= 0.d+0.dd+0.ddd+….+0.dd…d

w(d,n)= 0.d+2×0.dd+3×0.ddd+…..+n×0.dd…..d 输入正整数d(1≤d≤9),n(1≤n<10000),试精确求和s(d,n)与w(d,n)。同时统计:在s(d,n)与w(d,n)的n个小数位中,共有多少个小数位s与w对应位的数字相同? 测试数据: d=8,n=50; d=6,n=2013 4 解不等式

设n为正整数,a,b已知,解不等式a<1+1/(1+1/3)+...+1/(1+1/3+...+1/(2n-1)(1) a=100,b=1000 (2) a=2013,b=2014 参考解答:

解:上下限一般为键盘输入的a,b。

分两段求和:应用条件s

#include #include void main() { long a,b,c,d,i; double ts,s;

printf(\请输入a,b: \scanf(\i=0;ts=0;s=0; while(s

ts=ts+(double)1/(2*i-1); s=s+1/ts; } c=i;

while(s

ts=ts+(double)1/(2*i-1); s=s+1/ts; } d=i-1;

printf(\满足不等式的正整数n为: %ld≤n≤%ld \\n\}

请输入a,b: 100,1000

满足不等式的正整数n为: 329≤n≤4629 请输入a,b: 2013,2014

满足不等式的正整数n为: 10121≤n≤10125 实训5. 分数不等式

试解以下关于正整数n的不等式 M<1+1/2-1/3+1/4+1/5-1/6+….+或-1/n

其中m为从键盘输入的正整数,式中符号为二个“+”号后一个“-”号,即分母能被3整除时符号为“-”。

测试数据: m=4; m=7 5 解不定方程 解三元不定方程

1/a-1/b-1/c=1/(a+b+c)

求满足条件 x<=a,b,c<=y,b

(1) x=400,y=1000 (2) x=1000,y=2500 参考解答:

(1)枚举设计要点

1)为了扩大求解范围,所涉变量设置为double型。 2)注意a,b,c的取值范围,在区间[x,y]中取值:

由约定知a

3)另外,原三元不定方程为分数形式,转化为以下的整数形式 (a+b+c)*(b*c-a*c-a*b)=a*b*c

在枚举循环中应用以上整式进行筛选是可行的。 (2)枚举描述 // 解不定方程 #include #include void main()

{ double a,b,c,s,x,y,m; printf(\请输入正整数x,y: \scanf(\m=0;

for(a=x;a<=y-2;a++) // 设计三重循环实现枚举 for(b=a+1;b<=y-1;b++) for(c=b+1;c<=y;c++) { s=a+b+c;

if((b*c-a*b-a*c)*s!=a*b*c) // 应用方程式实施筛选 continue;

m++; // 统计解的个数并输出解

printf(\} }

请输入正整数x,y: 400,1000 1: a=408,b=984,c=986

请输入正整数x,y: 1000,2500 1: a=1015,b=2436,c=2465 2: a=1020,b=2460,c=2465 3: a=1026,b=2470,c=2484

6 递推序列

设集合M定义如下: (1) 1∈M

(2) x∈M => 2x+1∈M,5x-1∈M (3) 再无其它的数属于M。

试求集合M元素从小到大排列所得序列的第n项与前n项之和。 输入正整数n(n<10000),输出序列的第n项与前n项之和。 数据测试: (1) n=100 (2) n=2013 参考解答: 1. 枚举设计

(1)枚举设计要点

设递推序列的第i项为m(i),显然m(1)=1。

设置枚举变量k: k从2开始递增1取值,若k可由已有的项m(j)(j

// 2x+1,5x-1递推序列枚举判别 #include void main()

{ int n,i,j; long k,s,m[10000]; printf(\请输入n:\scanf(\m[1]=1;s=1;

k=1;i=1; // 确定初始值 while(i

for(j=1;j<=i;j++)

if(k==2*m[j]+1 || k==5*m[j]-1)

{ i++;m[i]=k; // 判断k为递推项,给m数组赋值 s=s+k; break; } }

printf(\}

2. 递推设计

(1) 递推设计要点

该题有2x+1,5x-1两个递推关系,设置数组m(i)存储M元素从小到大排列序列的第i项,显然m(1)=1,这是递推的初始条件。 同时设置两个队列: 2*m(p2)+1, p2=1,2,3,? 5*m(p5)-1, p5=1,2,3,?

这里用p2表示2x+1这一队列的下标,用p5表示5x-1这一队列的下标。

从两队列中选一排头,通过比较选数值较小者送入数组m中。所谓“排头”就是队列中尚未选入m的最小的下标。

若2*m(p2)+1<5*m(p5)-1, 则m(i)=2*m(p2)+1;下标p2增1; 若2*m(p2)+1>5*m(p5)-1, 则m(i)=5*m(p5)-1;下标p5增1;

若2*m(p2)+1=5*m(p5)-1, 则m(i)=5*m(p5)-1;下标p2与p5同时增1。 (2) 递推描述 // 双关系递推 #include void main()

{long n,p2,p5,i,s,m[10000]; printf(\请输入n:\

scanf(\m[1]=1;s=1;

p2=1;p5=1; // 排头p2,p5赋初值 for(i=2;i<=n;i++)

{ if(2*m[p2]+1<5*m[p5]-1) { m[i]=2*m[p2]+1;p2++;} else

{ m[i]=5*m[p5]-1;

if(2*m[p2]+1==5*m[p5]-1) p2++; // 为避免重复项,P2须增1 p5++; }

s+=m[i]; // 实现求和 }

printf(\}

请输入n:100

m(100)=1444,s=55021

请输入n:2013

m(2013)=157879,s=128116164 实训6. 振动数列 已知递推数列:

a(1)=1,a(2*i)=a(i)+2,a(2*i+1)=a(i+1)-a(i),(i=1,2,?)

数列平台定义:数列中相连两项或相连两项以上相等,则称为一个平台。 数列波峰定义:

(1) 若某项同时大于其前、后相邻项;

(2) 若存在相连若干项相等,这些项同时大于其相邻前项与后项。

例如相连的某3项为4,7,5,则为一个波峰;相连的某4项为-1,3,3,2,也为一个波峰,其中3,3为一个平台。

对指定的正整数m,n(m

测试数据: m=1000,n=2014 7 子数对最大值 TUIJIAN

设b是正整数a去掉一个数字后的正整数,对于给出的正整数n,如果a+b=n(n>10),则称正整数对a,b为整数n的一组子数对。 例如,n=34时,有3组子数对:(27,7),(31,3),(32,2)。 试求给定区间[x,y]中整数的子数对组数的最大值。

输入区间x,y (10

(1) x=100,y=999 (2) x=2013,y=3000 参考解答: 1. 设计要点

(1)根据给出的n设置整数a的枚举循环,对每一个a,计算b=n-a。

对于给定的n,确定枚举a的取值范围必须慎重:范围太小,可能造成遗解;范围太大,造

成无效操作太多。

注意到b≥1(有可能取1),因而取a循环终点为n-1。 由a>b,a+b=n可知a>n/2,因而取n/2为a循环起点。

(2)设计赋值表达式d=a/(t*10)*t+a%t; 生成a的去数字数。

事实上,当t=1时,表达式为d=a/10; d即为a的去个位数字后的数; 当t=10时,表达式为d=a/100*10+a; d即为a的去十位数字后的数; ??

依此类推,设a是一个m位数,应用t可实现生成a的m个去数字数。这些去数字数逐个与b=n-a进行比较并决定取舍。 2. 枚举描述 // 整数对

#include void main()

{ int a,b,c,n,k,j,t,x,y,max; long p[100],q[100];

printf(\请输入整数x,y: \max=0;

for(n=x;n<=y;n++) {k=0;

for(a=n/2;a<=n-1;a++) { b=n-a;t=1;

while(a>t) // 应用t控制去数字循环次数 { d=a/(t*10)*t+a%t; // d为a的一个去数字数 if(d==b) { k++;

p[k]=a*10000+b; }

t=t*10; } }

if(k>max) { max=k;c=a;

for(j=1;j<=k;j++) q[j]=p[j]; } }

printf(\最大值为%d\\n\printf(\如%d:\for(j=1;j<=max;j++)

printf(\}

请输入整数x,y: 100,999 最大值为5

如202:(151,51),(184,18),(186,16),(191,11),(201,1) 请输入整数x,y: 2013,9999

最大值为7

如2014:(1507,507),(1827,187),(1831,183),(1832,182),(1857,157), (1907,107),(2007,7)

8 统计n!中数字“0”的个数

设n为正整数,定义n!=1×2×3×?×n,统计n!中数字“0”的个数及其尾部连续“0”的个数。 输入正整数n(n<10000),输出n!中数字“0”的个数及其尾部连续“0”的个数。数据测试: (1) n=1000 (2) n=2013 参考解答:

解:n规模较大,n!的位数也就相应地大,设计a数组存储n!的各位数字,a[1]存储个位数字,a[2]存储十位数字,余类推。 1) 算法设计要点

模拟整数竖式乘运算实施精确计算。

通过常用对数累加和s=lg2+lg3+?+lgn确定n!的位数m=s+1,即a数组元素的个数。设置2重循环,模拟整数竖式乘法实施各数组元素的累乘: 乘数k:k=2,3,?,n;

累乘积各位a[j]:j=1,2,?,m; 实施乘运算:

t=a[j]*k+g; // 第j位乘k,g为进位数

a[j]=t; // 乘积t的个位数字存于本元素 g=t/10; // 乘积t的十位以上数字作为进位数 计算n!完成后,在j(1——m)循环中通过 if(a[j]==0) p++;

统计n!中数字“0”的个数p。

应用q=1; while(a[q]==0) q++;统计尾部连续“0”的个数q-1。 2)程序设计

// 统计n!中0的个数及尾部连续0的个数(n<10000) #include #include void main()

{ int g,j,k,m,n,p,q,t,a[40000];double s; printf(\请输入正整数n(n<10000): \scanf(\输入n s=0;

for(k=2;k<=n;k++)

s+=log10(k); // 对数累加确定n!的位数m

m=(int)s+1;;for(k=1;k<=m;k++);a[k]=0;//数组清零;a[1]=1;g=0;;for(k=2;k<=n;k++);for(j=1;j<=m;j++);{t=a[j]*k+g;//数组累乘并进位a[j;g=t/10;//统计0个数;p=0;;for(j=m;j>=1;j--);if(a[j]==0)p+ m=(int)s+1;

for(k=1;k<=m;k++) a[k]=0; // 数组清零 a[1]=1;g=0;

for(k=2;k<=n;k++)

for(j=1;j<=m;j++)

{ t=a[j]*k+g; // 数组累乘并进位 a[j]=t; g=t/10; //统计0个数 } p=0;

for(j=m;j>=1;j--)

if(a[j]==0) p++; // p统计n!中0的个数 q=1;

while(a[q]==0) q++; // q尾部连续0的个数 printf(\输出结果 } 数据测试:

请输入正整数n(n<10000): 1000 p=472,q=249

请输入正整数n(n<10000): 2013 p=1032,q=501

本文来源:https://www.bwwdw.com/article/0njo.html

Top