程序设计竞赛基础实训42Word格式文档下载.docx
- 文档编号:19336682
- 上传时间:2023-01-05
- 格式:DOCX
- 页数:22
- 大小:45.37KB
程序设计竞赛基础实训42Word格式文档下载.docx
《程序设计竞赛基础实训42Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《程序设计竞赛基础实训42Word格式文档下载.docx(22页珍藏版)》请在冰豆网上搜索。
f=0;
g=0;
for(j=1;
j<
j++)
{c=d%10;
d=d/10;
if(c==7)f++;
//统计数字7的个数
if(c==4)g++;
//统计数字4的个数
}
if(f>
0)s1++;
//统计含数字7且不能被7整除数的个数
g==0)s2++;
//统计其中不含数字4的个数
}
s1=%ld,s2=%ld\n"
s1,s2);
}
(3)程序运行示例
请输入位数m(2<
=k<
5
s1=32152,s2=20412
6
s1=366522,s2=208300
变通1:
试统计含有数字7且能被7整除的没有重复数字的m位整数的个数s1,并指出其中最大的一个数。
为了比较是否存在重复数字,设置f数组,f[3]=2为2个数字“3”。
{intc,e,g,i,j,m,f[10];
longb,d,s1,t;
for(j=0;
=9;
j++)f[j]=0;
//数组清零
f[c]++;
//统计数字c的个数
for(g=0,j=0;
j++)
if(f[j]>
1)g=1;
//存在重复数字标注g=1
if(f[7]>
t%7==0&
g==0)
{s1++;
e=t;
}//统计个数,并把满足条件的数赋值给e
s1=%ld,e=%d\n"
s1,e);
s1=1978,e=98763
s1=11704,e=987651
变通2:
试统计恰含一个数字7与2个数字4且能被7整除的m(m>
3)位整数的个数s1,并指出其中从小到大排序的第n个数。
#include<
{intc,e,i,j,m,n,f[10];
请输入m,n:
%d,%d"
m,&
n);
for(j=0;
}
if(f[7]==1&
f[4]==2&
t%7==0)
if(s1==n)e=t;
//统计个数,并把第n个数赋值给e
6,1000
s1=4096,e=417242
9真分数最值
统计分母在指定区间[a,b]的最简真分数(分子小于分母,且分子分母无公因数)共有多少个,并求其中最接近指定分数x/y的最简真分数。
输入a,b,输出[a,b]中最简真分数的个数、指出最接近417/2011的最简真分数。
测试数据:
a=10,b=99,输出:
a=100,b=999,输出:
(1)设计要点
设计求解一般情形:
统计分母在指定区间[a,b]的最简真分数的个数,并求这些最简真分数的和(正整数a,b从键盘输入)。
设分数分子为i,分母为j,最简真分数的个数为n,其和为s。
在指定范围[a,b]内枚举分数的分母j:
a——b;
同时对每一个分母j枚举分子i:
1——j-1。
对每一分数i/j,置标志t=0,然后进行是否存在公因数的检测。
如果分子i与分母j存在大于1的公因数u,说明i/j非最简真分数,应予舍略。
因为分子分母同时约去u后,分母可能不在[a,b],即使在[a,b]时前面已作了统计求和。
注意到公因数u的取值范围为[2,i],因而设置u循环在[2,i]中枚举,若满足条件
j%u==0&
i%u==0
说明分子分母存在公因数,标记t=1后退出,不予统计与求和。
否则保持原t=0,说明分子分母无公因数,用n实施迭代“n=n+1”统计个数。
为了求最接近s=x/y的最简真分数,设双精度型变量smin存储|i/j-x/y|的最小值,把分数i/j转变为double型减去s并求绝对值与smin比较,若fabs((double)i/j-s)<
smin,则把fabs((double)i/j-s)赋值给smin,同时用i1存储i,用j存储1j。
每得一个最简真分数i/j,就与smin比较一次。
枚举完成,则i1/j1即为所求最接近x/y的最简真分数。
(2)求最简真分数程序设计
//求分母在[a,b]的最简真分数的个数,及最接近x/y的分数
math.h>
{inta,b,i,j,i1,j1,t,u,x,y;
longn;
doubles,smin;
最简真分数分母在[a,b]内,请确定a,b:
a,&
b);
//输入区间的上下限
指定分数为x/y,请确定x,y:
x,&
y);
//输入指定分数
n=0;
s=(double)x/y;
smin=10;
for(j=a;
=b;
j++)//枚举最简真分数的分母
for(i=1;
=j-1;
i++)//枚举最简真分数的分子
{for(t=0,u=2;
u<
=i;
u++)//枚举因数
if(j%u==0&
i%u==0)
{t=1;
break;
}//分子分母有公因数,则舍去
if(t==0)
{n++;
//统计最简真分数个数
if(fabs((double)i/j-s)<
smin)
{smin=fabs((double)i/j-s);
i1=i;
j1=j;
//比较求最接近x/y的最简真分数
}
printf("
最简真分数个数:
%ld\n"
n);
最接近%d/%d的最简真分数为:
%d/%d\n"
x,y,i1,j1);
10,99
417,2011
2976
最接近417/2011的最简真分数为:
17/82
最简真分数分母在[a,b]内,请确定a,b:
100,999
300788
62/299
10特定数字组成的平方数
用数字2,3,5,6,7,8,9可组成多少个没有重复数字的7位平方数?
解:
求出最小7位数的平方根b,最大7位数的平方根c.
用a枚举[b,c]中的所有整数,计算d=a*a,这样确保所求平方数在d中。
设置f数组统计d中各个数字的个数。
如果f[3]=2,即平方数d中有2个“3”。
检测若f[k]>
1(k=0——9),说明d中存在有重复数字,返回。
在不存在重复数字的情形下,检测若f[0]+f[1]+f[4]=0,说明7位平方数d中没有数字“0”,“1”,“4”,d满足题意要求,打印输出。
//组成没有重复数字的7位平方数
{intk,m,n,t,f[10];
longa,b,c,d,w;
n=0;
b=sqrt(2356789);
c=sqrt(9876532);
for(a=b;
a<
=c;
a++)
{d=a*a;
w=d;
//确保d为平方数
for(k=0;
k<
k++)f[k]=0;
while(w>
0)
{m=w%10;
f[m]++;
w=w/10;
for(t=0,k=1;
k++)
if(f[k]>
1)t=1;
//测试平方数是否有重复数字
if(t==0&
f[0]+f[1]+f[4]==0)//测试平方数中没有数字0,1,4
{n++;
%2d:
%ld=%ld^2\n"
d,a);
共可组成%d个没有重复数字的7位平方数.\n"
1:
3297856=1816^2
2:
3857296=1964^2
3:
5827396=2414^2
4:
6385729=2527^2
5:
8567329=2927^2
6:
9572836=3094^2
共可组成6个没有重复数字的7位平方数.
用1,2,…,9这9个数字可以组成多少个没有重复数字的9位平方数?
//组成没有重复数字的9位平方数
b=(int)sqrt(123456789);
c=(int)sqrt(987654321);
f[0]==0)//测试平方数中没有重复数字,也没有数字0
共可组成%d个没有重复数字的9位平方数.\n"
1:
139854276=11826^2
152843769=12363^2
157326849=12543^2
215384976=14676^2
245893761=15681^2
254817369=15963^2
7:
326597184=18072^2
8:
361874529=19023^2
9:
375468129=19377^2
10:
382945761=19569^2
11:
385297641=19629^2
12:
412739856=20316^2
13:
523814769=22887^2
14:
529874361=23019^2
15:
537219684=23178^2
16:
549386721=23439^2
17:
587432169=24237^2
18:
589324176=24276^2
19:
597362481=24441^2
20:
615387249=24807^2
21:
627953481=25059^2
22:
653927184=25572^2
23:
672935481=25941^2
24:
697435281=26409^2
25:
714653289=26733^2
26:
735982641=27129^2
27:
743816529=27273^2
28:
842973156=29034^2
29:
847159236=29106^2
30:
923187456=30384^2
共可组成30个没有重复数字的9位平方数.
11构建横竖折对称方阵
试观察图所示的横竖折对称方阵的构造特点,总结归纳其构造规律,设计并输出n(奇数)阶对称方阵。
图7阶横竖对称方阵
输出15阶、19阶横竖折对称方阵。
解:
这是一道培养与锻炼观察能力、归纳能力与设计能力的有趣案例。
设置2维数组a[n][n]存储n阶方阵的元素,数组a[n][n]就是数据结构。
本案例求解算法主要是给a数组赋值与输出。
一个一个元素赋值显然行不通,必须根据方阵的构造特点,归纳其构建规律,分区域给各元素赋值。
(1)构造规律与赋值要点
观察横竖折对称方阵的构造特点,方阵横向与纵向正中有一对称轴。
两对称轴所分4个小矩形区域表现为同数字横竖折递减,至4顶角元素为1。
设阶数n(奇数)从键盘输入,对称轴为m=(n+1)/2。
设置2维a数组存储方阵中元素,行号为i,列号为j,a[i][j]为第i行第j列元素。
可知主对角线(从左上至右下)有:
i=j;
次对角线(从右上至左下)有:
i+j=n+1。
按两条对角线把方阵分成上部、左部、右部与下部4个区,如图所示。
图对角线分成的4个区
对角线上元素可归纳到上、下部,即上、下部区域带等号即可。
上、下部按列号j的函数m-abs(m-j)赋值:
if(i+j<
=n+1&
i<
=j||i+j>
i>
=j)
a[i][j]=m-abs(m-j);
左、右部按行号i的函数m-abs(m-i)赋值:
n+1&
j||i+j>
j)
a[i][j]=m-abs(m-i);
输出时,按m-a[i][j]打印。
(2)程序设计
//横竖折对称方阵
//调用2个头文件
{inti,j,m,n,a[30][30];
//定义数据结构
请确定方阵阶数(奇数)n:
if(n%2==0){printf("
请输入奇数!
"
return;
m=(n+1)/2;
=n;
i++)
{if(i+j<
//方阵上、下部元素赋值
//方阵左、右部元素赋值
%d阶对称方阵为:
\n"
i++)
{for(j=1;
j++)//输出对称方阵
%3d"
m-a[i][j]);
12倒立的勾股数
把求勾股数变通为求倒立的勾股数。
定义满足方程式
的正整数x,y,z,称为一组倒立的勾股数。
试求指定区间[a,b]内的倒立勾股数组。
(1)求指定区间[30,100]内的倒立勾股数组.
(2)求指定区间[100,200]内的倒立勾股数组.
显然,倒立勾股数组中x,y不可能相等,且x,y>
z。
为避免重复,不妨设x>
y>
在指定区间[a,b]上根据x,y,z的大小关系设置循环:
z从a至b-2,y从z+1至b-1,x从y+1至b。
对每一组x,y,z,如果直接应用条件式
1/(x*x)+1/(y*y)=1/(z*z)
作判别,因分数计算的不可避免的误差,有可能把一些成立的倒立勾股数组解遗失,即造成遗漏。
注意到上述分数条件式作通分整理得到的下面的正整数条件式
z*z*(x*x+y*y)=x*x*y*y
程序中为防止发生解的遗漏,应用上述整数条件作判别是适宜的。
(2)求区间内倒立勾股数程序设计
//求指定区间内倒立勾股数组
{inta,b,n;
longx,y,z;
求指定区间[a,b]内倒立的勾股数组."
\n请输入区间[a,b]的上下限a,b:
\n区间[%d,%d]中倒立的勾股数组有:
a,b);
for(z=a;
z<
=b-2;
z++)
for(y=z+1;
y<
=b-1;
y++)
for(x=y+1;
x<
x++)
if(z*z*(x*x+y*y)==x*x*y*y)//满足倒立勾股数条件时输出
1/%ld^2+1/%ld^2=1/%ld^2\n"
x,y,z);
共%d组勾股数."
区间[30,100]中倒立的勾股数组有:
1/60^2+1/45^2=1/36^2
1/80^2+1/60^2=1/48^2
1/100^2+1/75^2=1/60^2
共3组勾股数.
区间[100,200]中倒立的勾股数组有:
1/180^2+1/135^2=1/108^2
1/200^2+1/150^2=1/120^2
共2组勾股数.
13基于素数的代数和
定义s(n)=1*3-3*5-5*7+7*9+9*11±
…-25*27±
…±
(2n-1)*(2n+1)
(一般项(2k-1)*(2k+1)的符号识别:
当(2k-1)与(2k+1)中有且只有一个素数,取“+”;
其余取“-”。
)
1)求s(1000)。
2)设1<
=n<
=1000,当n为多大时,s(n)最大。
3)设1<
=1000,当n为多大时,s(n)最小。
(1)C程序设计
//基于素数的整数和
#include<
{intt,j,n,k,k1,k2,a[3000];
longs,smax,smin;
请输入整数n:
for(k=1;
=n+1;
k++)a[k]=0;
for(k=2;
{for(t=0,j=3;
=sqrt(2*k-1);
j+=2)
if((2*k-1)%j==0)
{t=1;
if(t==0)a[k]=1;
//标记第k个奇数2k-1为素数
s=0;
smax=0;
smin=10000;
{if(a[k]+a[k+1]==1)
s+=(2*k-1)*(2*k+1);
//实施代数和
else
s-=(2*k-1)*(2*k+1);
if(s>
smax){smax=s;
k1=k;
}//比较求最大值smax
if(s<
smin){smin=s;
k2=k;
}//比较求最大值smin
s(%d)=%ld\n"
n,s);
当k=%d时s有最大值:
%ld\n"
k1,smax);
当k=%d时s有最小值:
k2,smin);
(2)运行结果
300
s(300)=1142382
当k=255时s有最大值:
2986031
当k=174时s有最小值:
-174700
请输入整数n:
1000
s(1000)=-161348876
当k=387时s有最大值:
7076531
当k=985时s有最小值:
-181070411
14幂序列
1.问题提出
求解双幂集合
的元素由小到大排序的第n项与前n项之和。
输入正整数n,输出序列第n项与前n项之和。
(1)40
(2)46
2.幂序列求解要点
集合由2的幂与3的幂组成,实际上给出的是两个递推关系。
为了实现从小到大排列,设置a,b两个变量,a为2的幂,b为3的幂,显然a≠b。
设置k循环(k=1,2,…,n,其中n为键盘输入整数),在k循环外赋初值:
a=2,b=3,s=0。
在k循环中通过比较赋值:
当a<
b时,由赋值f(k)=a确定为序列的第k项;
然后a=a*2,即a按递推规律乘2,为后一轮比较作准备;
当a>
b时,由赋值f(k)=b确定为序列的第k项;
然后b=b*3,即b按递推规律乘3,为后一轮比较作准备。
每计算一项f(k),通过累加实现求和:
s=s+f(k)。
3.幂序列程序实现
//幂序列求解
{intk,n,t,p2,p3;
longa,b,s,f[100];
求数列的第n项与前n项和,请输入n:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 程序设计 竞赛 基础 42