程序设计大赛题目解答文档格式.docx
- 文档编号:17334596
- 上传时间:2022-12-01
- 格式:DOCX
- 页数:38
- 大小:35.50KB
程序设计大赛题目解答文档格式.docx
《程序设计大赛题目解答文档格式.docx》由会员分享,可在线阅读,更多相关《程序设计大赛题目解答文档格式.docx(38页珍藏版)》请在冰豆网上搜索。
doublesum1=1,sum2=1,g;
请输入n:
"
while(n1<
{
n1++;
if(n1%2==0)
sum2+=-(double)1/n1;
elsesum2+=(double)1/n1;
g=sqrt(n1);
if(n1%3==0)
sum1+=-g/sum2;
else
sum1+=g/sum2;
%lf\n"
sum1);
2.幂积序列
设x,y为非负整数,试计算集合
的元素不大于指定整数n的个数k,并求这些元素从小到大排序的第m项f。
输入n,m,输出k,f。
n=10000,m=50输出:
n=10000000,m=100输出:
幂积序列复杂在“积”字上,即幂积序列的项既可以是2的幂,3的幂,也可以是这双幂的乘积。
我们应用枚举求解。
(1)设计要点
集合元素由2的幂与3的幂及其乘积组成,设元素从小到大排序的第k项为f(k)。
显然,f
(1)=1,f
(2)=2。
设置a循环,a从3开始递增1至n,对每一个a(赋值给j),逐次试用2试商,然后逐次试用3试商。
试商后若j>
1,说明原a有2,3以外的因数,不属于该序列。
若j=1,说明原a只有2,3的因数,属于该序列,把a赋值给序列第k项。
由于实施从小到大测试赋值,所得项无疑是从小到大的序列。
当a达到指定的n,退出循环,输出指定项f(m)。
(2)枚举程序设计
//幂序列2^x*3^y枚举求解
{intk,m;
longa,j,n,f[1000];
计算不大于n的项数,请指定n:
%ld"
输出序列的第m项,请指定m:
m);
f[1]=1;
f[2]=2;
k=2;
for(a=3;
a<
=n;
a++)
{j=a;
while(j%2==0)j=j/2;
//反复用2试商
while(j%3==0)j=j/3;
//反复用3试商
if(j==1)
{k++;
f[k]=a;
}//用a给f[k]赋值
}
幂序列中不大于%ld的项数为:
%d\n"
n,k);
if(m<
=k)
从小到大排序的第%d项为:
%ld\n"
m,f[m]);
printf("
所输序号m大于序列的项数!
\n"
(3)程序运行示例
67,2304
190,93312
计算集合在指定区间[n1,n2]中有多少个元素?
3.喝汽水
定价1瓶汽水4角8分钱,同时规定3个空瓶可换回1瓶汽水,或20个空瓶可换回7瓶汽水。
例如用5元买10瓶汽水,然后用9个空瓶子换3瓶汽水,喝掉3瓶满的,喝完以后4个空瓶子,用3个再换一瓶,喝掉这瓶满的,这时候剩2个空瓶子。
然后你让老板先借给你一瓶汽水,喝掉这瓶满的,喝完以后用3个空瓶子换一瓶满的还给老板。
这样,5元可喝到15瓶汽水。
今有n元钱买汽水,最多可喝m瓶汽水。
n=100,m=
n=2011,m=
{
intn1=2011,n,sum,i;
doublen2;
n2=n1/0.48;
n=n2;
sum=n;
while(n>
20)
i=n/20;
sum+=i*7;
n=i*7+n%20;
=2)
i=n/3;
sum+=i;
n=i+n%3;
if(n==2)
{
sum++;
break;
}
sum);
原题:
有这样一道智力题:
“某商店规定:
三个空汽水瓶可以换一瓶汽水。
小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?
”答案是5瓶,方法如下:
先用9个空瓶子换3瓶汽水,喝掉3瓶满的,喝完以后4个空瓶子,用3个再换一瓶,喝掉这瓶满的,这时候剩2个空瓶子。
如果小张手上有n个空汽水瓶,最多可以换多少瓶汽水喝?
//规定3个空瓶可换回1瓶汽水。
开始有n个空瓶,最多可喝多少瓶汽水?
{longn,m,t,x;
请输入开始拥有的空瓶数n:
t=n;
m=0;
//确定初始值
while(t>
=3)
{x=t/3;
m=m+x;
//用3x个空瓶换回x瓶汽水
t=t-2*x;
//空瓶数减少2x个
用其中%ld个空瓶换回%ld瓶汽水。
3*x,x);
喝完后空瓶个数变为%ld.\n"
t);
if(t==2)
{m=m+1;
借1瓶汽水,再还3空瓶,两清.\n"
答案:
开始有%ld个空瓶,可喝%ld瓶汽水。
n,m);
请输入开始拥有的空瓶数n:
2012
用其中2010个空瓶换回670瓶汽水。
喝完后空瓶个数变为672.
用其中672个空瓶换回224瓶汽水。
喝完后空瓶个数变为224.
用其中222个空瓶换回74瓶汽水。
喝完后空瓶个数变为76.
用其中75个空瓶换回25瓶汽水。
喝完后空瓶个数变为26.
用其中24个空瓶换回8瓶汽水。
喝完后空瓶个数变为10.
用其中9个空瓶换回3瓶汽水。
喝完后空瓶个数变为4.
用其中3个空瓶换回1瓶汽水。
喝完后空瓶个数变为2.
借1瓶汽水,再还3空瓶,两清.
开始有2012个空瓶,可喝1006瓶汽水。
解:
因7/20>
1/3,因此只要空瓶数大于等于20,尽可能用20个空瓶可换回7瓶汽水。
直到空瓶数不足20时,用3个空瓶可换回1瓶汽水。
由20空瓶=7汽水+7空瓶
得1空瓶=7/13汽水
由3空瓶=1汽水+1空瓶
得1空瓶=1/2汽水
设置变量k统计汽水瓶数,t统计空瓶数。
//规定1瓶汽水48分钱,今有n元钱;
规定3个空瓶可换回1瓶汽水,
//或20个空瓶可换回7瓶汽水。
问最多可喝多少瓶汽水?
{longk,n,t,x;
请输入n:
k=n*100/48;
t=k;
//k为汽水瓶数,t为空瓶数
有%ld元钱,可买回%ld瓶汽水。
if(n*100>
k*48)printf("
尚余%ld分钱。
n*100-k*48);
\n喝完%ld瓶汽水后,空瓶按以下方案换回汽水:
k);
=20)
{x=t/20;
k=k+7*x;
//用20x个空瓶换回7x瓶汽水
t=t-13*x;
//空瓶数减少13x个
20*x,7*x);
}
if(t>
=13)
{k=k+7;
t=t-13;
借7瓶汽水,再还20空瓶,空瓶个数变为%ld.\n"
k=k+x;
{k=k+1;
借1瓶汽水,再还3空瓶.\n"
有%ld元钱,最多可喝%ld瓶汽水。
100
有100元钱,可买回208瓶汽水。
尚余16分钱。
喝完208瓶汽水后,空瓶按以下方案换回汽水:
用其中200个空瓶换回70瓶汽水。
喝完后空瓶个数变为78.
用其中60个空瓶换回21瓶汽水。
喝完后空瓶个数变为39.
用其中20个空瓶换回7瓶汽水。
喝完后空瓶个数变为13.
借7瓶汽水,再还20空瓶,空瓶个数变为0.
有100元钱,最多可喝320瓶汽水。
2011
有2011元钱,可买回4189瓶汽水。
尚余28分钱。
喝完4189瓶汽水后,空瓶按以下方案换回汽水:
用其中4180个空瓶换回1463瓶汽水。
喝完后空瓶个数变为147
用其中1460个空瓶换回511瓶汽水。
喝完后空瓶个数变为523.
用其中520个空瓶换回182瓶汽水。
喝完后空瓶个数变为185.
用其中180个空瓶换回63瓶汽水。
喝完后空瓶个数变为68.
喝完后空瓶个数变为29.
喝完后空瓶个数变为16.
借7瓶汽水,再还20空瓶,空瓶个数变为3.
喝完后空瓶个数变为1.
有2011元钱,最多可喝6444瓶汽水。
省去过程,简化设计:
x=t/13;
//实现1空瓶=7/13瓶汽水
x=t/2;
//实现1空瓶=1/2瓶汽水
%ld元钱最多可喝%ld瓶汽水。
100元钱最多可喝320瓶汽水。
2011元钱最多可喝6444瓶汽水。
4.解佩尔方程
1.案例背景
佩尔(Pell)方程是关于x,y的二次不定方程,表述为
(其中n为非平方正整数)
当x=1或x=-1,y=0时,显然满足方程。
常把x,y中有一个为零的解称为平凡解。
我们要求佩尔方程的非平凡解。
佩尔方程的非平凡解很多,这里只要求出它的最小解,即x,y为满足方程的最小正数的解,又称基本解。
对于有些n,尽管是求基本解,其数值也大得惊人。
这么大的数值,如何求得?
其基本解具体为多少?
可以说,这是自然界对人类计算能力的一个挑战。
十七世纪曾有一位印度数学家说过,要是有人能在一年的时间内求出x2-92y2=1的非平凡解,他就算得上一名真正的数学家。
由此可见,佩尔方程的求解是有趣的,其计算也是繁琐的。
输入n=92,方程的基本解:
输入n=73,方程的基本解:
2.枚举设计
应用枚举试值来探求佩尔方程的基本解。
设置y从1开始递增1取值,对于每一个y值,计算a=n*y*y后判别:
若a+1为某一整数x的平方,则(x,y)即为所求佩尔方程的基本解。
若a+1不是平方数,则y增1后再试,直到找到解为止。
应用以上枚举探求,如果解的位数不太大,总可以求出相应的基本解。
如果基本解太大,应用枚举无法找到基本解,可约定一个枚举上限,例如10000000。
可把y<
=10000000作为循环条件,当y>
10000000时结束循环,输出“未求出该方程的基本解!
”而结束。
3.程序设计
//解PELL方程:
x^2-ny^2=1
{doublea,m,n,x,y;
解PELL方程:
x^2-ny^2=1.\n"
请输入非平方整数n:
%lf"
m=floor(sqrt(n+1));
if(m*m==n)
{printf("
n为平方数,方程无正整数解!
return;
y=1;
while(y<
=10000000)
{y++;
//设置y从1开始递增1枚举
a=n*y*y;
x=floor(sqrt(a+1));
if(x*x==a+1)//检测是否满足方程
{printf("
方程x^2-%.0fy^2=1的基本解为:
n);
x=%.0f,y=%.0f\n"
x,y);
break;
if(y>
10000000)
未求出该方程的基本解!
4.程序运行示例与说明
x^2-ny^2=1.
73
方程x^2-73y^2=1的基本解为:
x=2281249,y=267000
为了提高求解方程的范围,数据结构设置为双精度(double)型。
如果设置为整形或长整形,方程的求解范围比设置为双精度型要小。
例如n=73时,设置整形或长整形就不可能求出相应方程的解。
可见,数据结构的设置对程序的应用范围有着直接的影响。
对某些n,相应佩尔方程解的位数太大。
例如当n=991时,相应佩尔方程的基本解达30位。
此时只有通过某些专业算法(例如连分数法)才能进行求解。
5.分解质因数
整数分解质因数是最基本的分解。
例如,90=2*3*3*5,1960=2^3*5*7^2,前者为质因数乘积形式,后者为质因数的指数形式。
把指定区间上的所有整数分解质因数,每一整数表示为质因数从小到大顺序的乘积形式。
如果被分解的数本身是素数,则注明为素数。
例如,92=2*2*23,91(素数!
)。
分解:
1671861=
5845271=
6.构建横竖折对称方阵
试观察图所示的横竖折对称方阵的构造特点,总结归纳其构造规律,设计并输出n(奇数)阶对称方阵。
图7阶横竖对称方阵
输出15阶、19阶横竖折对称方阵。
10.统计
试统计含有数字7且不能被7整除的m位整数的个数s1,并指出这s1个数中不含有数字4的整数的个数s2。
输入m,输出s1,s2。
m=5,输出:
m=6,输出:
(1)设计要点
首先通过乘m-1个10计算m位数的起点b=10^(m-1),为枚举提供范围t(b—10*b-1)。
为了检测m位数t含有多少个数字7,每个m位整数t赋给d(以保持t不变),然后通过m次求余先后分离出t的m个数字c,if(c==7)f++,统计整数t中数字7的个数f。
同时统计数字4的个数g。
如果f>
0,说明整数t中含有数字7。
如果g=0,说明整数t中不含数字4。
对每一个m位整数,据f>
0&
&
t%7>
0,s1作相应统计。
据f>
g==0,s2作相应统计。
(2)程序设计
//统计含数字7且不能被7整除的m位整数的个数s1,其中不含数字4的个数s2
{intc,f,g,i,j,m;
longb,d,s1,s2,t;
请输入位数m(2<
=m<
=9):
b=1;
s1=0;
s2=0;
for(i=2;
i<
=m;
i++)b=b*10;
//计算m位数的起点
for(t=b;
t<
=10*b-1;
t++)//枚举每一个m位数
{d=t;
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整除数的个数
if(f>
g==0)s2++;
//统计其中不含数字4的个数
s1=%ld,s2=%ld\n"
s1,s2);
请输入位数m(2<
=k<
5
s1=32152,s2=20412
6
s1=366522,s2=208300
变通:
求m(m>
3)位整数中恰含有2个7且恰含有1个4的整数的个数.
11.构建斜折对称方阵
试观察图所示的斜折对称方阵的构造特点,总结归纳其构造规律,设计并输出n(奇数)阶斜折对称方阵。
图7阶斜折对称方阵
输出15阶、19阶斜折对称方阵。
(1)构造规律与赋值要点
斜折对称方阵的构造特点:
两对角线上均为“0”,依两对角线把方阵分为4个区域,每一区域表现为同数字依附两对角线折叠对称,至上下左右正中元素为n/2。
同样设置2维a[n][n]数组存储方阵中元素,行号为i,列号为j,a[i][j]为第i行第j列元素。
令m=(n+1)/2,按m把方阵分成的4个小矩形区如图所示。
图按m分成的4个小矩形
注意到方阵的主对角线(从左上至右下)上元素为:
i=j,则左上区与右下区依主对角线赋值:
a[i][j]=abs(i-j);
注意到方阵的次对角线(从右上至左下)上元素为:
i+j=n+1,则右上区与左下区依次对角线赋值:
a[i][j]=abs(i+j-n-1);
//斜折对称方阵
{inti,j,m,n,a[30][30];
请确定方阵阶数(奇数)n:
if(n%2==0)
请输入奇数!
return;
m=(n+1)/2;
for(i=1;
i++)
{if(i<
=m&
j<
=m||i>
m&
j>
m)
a[i][j]=abs(i-j);
//方阵左上部与右下部元素赋值
if(i<
m||i>
=m)
a[i][j]=abs(i+j-n-1);
//方阵右上部与左下部元素赋值
%d阶对称方阵为:
i++)
{for(j=1;
j++)//输出对称方阵
%3d"
a[i][j]);
运行以上两个程序,可以在欣赏各个具体的对称方阵中,感受从特例到一般的神奇。
12.台球碰撞
在平面直角坐标系下,台球桌是一个左下角在(0,0),右上角在(L,W)的矩形。
有一个球心在(x,y),半径为R的圆形母球放在台球桌上(整个球都在台球桌内)。
受撞击后,球沿极角为b的射线(即:
x正半轴逆时针旋转到此射线的角度为b)以初速度v飞出。
因球与桌面的磨擦,球作的加速度为a的匀减速率运动,每次碰到球桌边框时均发生完全弹性碰撞(反射角等于入射角)。
试求球停止时球心所在位置。
输入:
l=180,w=120,x=35,y=40,r=5,b=30,v=27,a=6
输出:
(87.61,70.37)
受撞击后,球沿极角为a的射线(即:
x正半轴逆时针旋转到此射线的角度为a)飞出,每次碰到球桌时均发生完全弹性碰撞(球的速率不变,反射角等于入射角)。
如果球的速率为v,s个时间单位之后球心在什么地方?
输入
输入文件最多包含25组测试数据,每个数据仅一行,包含8个正整数L,W,x,y,R,a,v,s(100<
=L,W<
=105,1<
=R<
=5,R<
=x<
=L-R,R<
=y<
=W-R,0<
=a<
360,1<
=v,s<
=105),含义见题目描述。
L=W=x=y=R=a=v=s=0表示输入结束,你的程序不应当处理这一行。
输出
对于每组数据,输出仅一行,包含两个实数x,y,表明球心坐标为(x,y)。
x和y应四舍五入保留两位小数。
样例输入
样例输出
1001008010590223
1101007010518019999
00000000
80.0056.00
71.0010.00
设计要点:
(1)
(1)确定球心区域
设球心座标为(x,y),则有球心矩形区域:
x1≤x≤x2,y1≤y≤y2
其中:
x1=r,x2=l-r;
y1=r,y2=w-r
(2)没撞击时球位置
设开始时球心位于(x0,y0),球沿极角为a的射线射出,球的速率为v,s
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 程序设计 大赛 题目 解答