《2022年程序设计竞赛基础实训》由会员分享,可在线阅读,更多相关《2022年程序设计竞赛基础实训(11页珍藏版)》请在金锄头文库上搜索。
1、2012 程序设计竞赛基础实训82 39 台球碰撞在平面直角坐标系下,台球桌是一个左下角在(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 原题:在平面直角坐标系下,台球桌是一个左下角在(0,
2、0) ,右上角在 ( L, W ) 的矩形。有一个球心在 ( x, y),半径为R 的圆形母球放在台球桌上(整个球都在台球桌内)。受撞击后,球沿极角为a 的射线(即: x 正半轴逆时针旋转到此射线的角度为a)飞出,每次碰到球桌时均发生完全弹性碰撞(球的速率不变,反射角等于入射角)。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 1 页,共 11 页如果球的速率为 v,s 个时间单位之后球心在什么地方?输入输入文件最多包含25 组测试数据,每个数据仅一行,包含8 个正整数L, W , x, y, R , a, v, s (100=L, W =105,
3、 1=R=5, R =x=L- R, R=y=W -R, 0=a360, 1= v, s=105),含义见题目描述。L=W =x=y=R=a=v=s=0 表示输入结束,你的程序不应当处理这一行。输出对于 每组 数据 ,输 出仅 一 行,包含 两 个实数x, y ,表明球心坐标为( x, y) 。x 和 y 应四舍五入保留两位小数。样例输入样例输出100 100 80 10 5 90 2 23 110 100 70 10 5 180 1 9999 0 0 0 0 0 0 0 0 80.00 56.00 71.00 10.00 设计要点 : (1)确定球心区域设球心座标为 (x,y),则有球心矩形
4、区域: x1xx2,y1yy2 其中: x1=r,x2=l-r。 y1=r,y2=w-r (2) 没撞击时球位置设开始时球心位于( x0,y0 ),球沿极角为a 的射线射出,球的速率为v,s个时间单位之后球心在 (x,y): x=x0+v*s*cos(a*3.14159/180) y=y0+v*s*sin(a*3.14159/180) (3) 撞击轴对称若球与右竖边( x2)撞击,撞击后横月座标为:x=2*x2-x 若球与上横边( y2)撞击,撞击后纵月座标为:y=2*y2-y 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 2 页,共 11 页程
5、序设计:/ 台球碰撞#include #include void main() double l,w,r,a,v,s,x,y,x1,x2,y1,y2。 printf( 请确定球台边框(l,w): )。scanf(%lf,%lf,&l,&w)。 printf( 请确定球心开始位置 (x,y): )。 scanf(%lf,%lf,&x,&y)。 printf( 请确定球半径 r: )。 scanf(%lf,&r)。 printf( 请确定射击角度 a: )。 scanf(%lf,&a)。 printf( 请确定射击速度 v: )。 scanf(%lf,&v)。 printf( 请确定时间 s: )
6、。 scanf(%lf,&s)。 x1=r 。x2=l-r 。y1=r。y2=w-r 。 x=x+v*s*cos(a*3.1415926/180)。 y=y+v*s*sin(a*3.1415926/180)。 while(xx2 | yy2) if(xx2) x=2*x2-x。 if(xy2) y=2*y2-y。 if(yy1) y=2*y1-y。 printf( 所求位置为 :(%.2f,%.2f).n,x,y)。 请确定球台边框 (l,w): 130,110 请确定球心开始位置 (x,y): 30,40 请确定球半径 r: 5 请确定射击角度a: 30 请确定射击速度v: 20 请确定时间
7、 s: 20 所求位置为 :(113.59,40.00). 引申:在平面直角坐标系下,台球桌是一个左下角在(0,0) ,右上角在 ( L, W )的矩形。有一个球心在(x,y) ,半径为r 的圆形母球放在台球桌上(整个球都在台球桌内)。受撞击后,球沿极角为b 的射线(即:与正半轴逆时针旋转到此射线的角度为b)以初速度v 飞出。因球与桌面的磨擦,球作的加速度为a的匀减速率运动,每次碰到球桌边框时均发生完全弹性碰撞(反射角等于入射角)。试求球停止时球心所在位置。解:球作的初速度为v0, 加速度为 a 的匀减速率运动,设t 时刻球的速度精选学习资料 - - - - - - - - - 名师归纳总结
8、- - - - - - -第 3 页,共 11 页为 vt, 则vt=v0-a*t 停止时 vt=0, 则运行时间为: t=v0/a 球运行距离为 s=v0*t-a*t*t/2=v0*v0/2/a / 台球碰撞#include #include void main() double l,w,r,a,b,v,s,x,y,x1,x2,y1,y2。 printf( 请确定球台边框 (l,w): )。 scanf(%lf,%lf,&l,&w)。 printf( 请确定球心开始位置(x,y): )。scanf(%lf,%lf,&x,&y)。 printf( 请确定球半径 r: )。 scanf(%lf,
9、&r)。 printf( 请确定射击角度 b: )。 scanf(%lf,&b)。 printf( 请确定射击初速度v: )。 scanf(%lf,&v)。 printf( 请确定匀减速的加速度a: )。 scanf(%lf,&a)。 x1=r 。x2=l-r 。y1=r。y2=w-r。 s= v*v/2/a。 x=x+s*cos(b*3.1415926/180)。 y=y+s*sin(b*3.1415926/180)。 while(xx2 | yy2) if(xx2) x=2*x2-x。 if(xy2) y=2*y2-y。 if(y1),求出其平方数s;计算 a 的位数 w ,同时计算 b=
10、10w,a 的平方 s 的尾部 c=s%b ;比较 a,c,若 a=c则输出守形数。(2) 程序实现/ 求x,y内的守形数#include void main() long int a,b,c,k,s,x,y。 printf( 求区间 x,y中的守形数 .) 。 printf( 请输入整数 x,y:)。 scanf(%ld,%ld,&x,&y)。 for(a=x。a0) b=b*10。k=k/10 。 c=s%b。 / c为 a 的平方数 s 的尾部 if(a=c) printf(%ld2=%ld n,a,s)。 (3) 程序运行结果求区间 x,y中的守形数 . 请输入整数 x,y:10,10
11、000 252=625 762=5776 3762=141376 6252=390625 93762=87909376 2. 探索 n 位守形数(1) 求解要点为了求更多位数的守形数,可应用守形数的性质:一个m 位守形数的尾部m-1位数也是一个守形数。道理很简单, a 是一个 m位数, a 的平方数尾部的m-1位仅由 a 的尾部 m-1位决定而与 a 的其他位无关。实施易知一位守形数有三个:1,5,6 。则二位守形数的个位数字只可能是1,5,6 这三个数字。根据这一思路,我们可应用递推求出多位守形数。(2) 程序设计精选学习资料 - - - - - - - - - 名师归纳总结 - - - -
12、 - - -第 5 页,共 11 页/ 求 n 位守形数#include void main() int n,d,k,j,i,t,m,w,z,u,v,a500,b500,c500。 printf(n=)。scanf(%d,&n)。 for(d=1。d=9。d+) for(k=1。k=500。k+) ak=0。bk=0 。ck=0 。 a1=d。 / 给个位数赋值 for(k=2。k=n。k+) for(j=0。j=9。j+) ak=j。v=0。 for(i=1。i=k 。i+) ci=0。 / 探索 a(k) for(i=1。i=k 。i+) for(z=0,t=1。t=k 。t+) u=ai
13、*at+z。z=u/10 。bi+t-1=u%10 。 / 计算平方 for(w=0,m=i。m=k 。m+) u=cm+bm+w。w=u/10。cm=u%10。 for(i=1。i=1。k-) printf(%d,ak)。printf(n)。 (3) 程序运行示例运行程序,输入 n=30,得 30 位守形数 5 结尾的 30守形数 : 1066199773922562599 6 结尾的 30守形数 : 893380022607743740081787109376 41 奇数序列运算式在由指定相连奇数 组成的序列的每相邻两项中插入运算符号:精选学习资料 - - - - - - - - - 名师
14、归纳总结 - - - - - - -第 6 页,共 11 页若相邻两项都是合数,则两项中插入“- ”号;若相邻两项一项合数一项素数,则两项中插入“+”号;若相邻两项都是素数,则两项中插入乘号“*”号;输入奇数b,c(bc) ,完成 b,c中奇数序列的运算式,并计算该式的运算结果。例如 b=31,c=45, 完成运算式为: 31+33-35+37+39+41*43+45=1913 测试数据:(1) b=3,c=51 (2) b=2011,c=2029 / 奇数序列运算式#define N 30000 #include #include void main() int b,c,f,m,n,k,i,
15、j,aN。 long t,s。 printf( 请输入首尾奇数b,c(bc): )。 scanf(%d,%d,&b,&c)。m=b-2。n=(c-m)/2 。 / 奇数序列 2k+m (k=1,2.,n) for(k=1。k=n+1。k+) ak=0。for(k=1 。k=n。k+) for(t=0,j=3。j=sqrt(2*k+m)。j+=2) if(2*k+m)%j=0) t=1。break。 if(t=0) ak=1。 / 标记第 k 个奇数 2k+m为素数 printf(n %d,b)。for(i=2。i=n 。i+) / 完成表达式 if(ai-1+ai=0) printf(-%d,
16、2*i+m)。 / 插入减号 if(ai-1+ai=1) printf(+%d,2*i+m)。 / 插入加号 if(ai-1+ai=2) printf(*%d,2*i+m)。 / 插入乘号 s=0。 a0=1-a1。 an+1=0 。for(i=1。i=n 。i+) / 计算表达式结果 t=2*i+m。f=i 。 while(ai+ai+1=2) i+。t=t*(2*i+m)。 / 相邻项均为素数时相乘if(af-1+af=0) s=s-t。if(af-1+af=1) s=s+t。 printf(=%d.n,s)。 请输入首尾奇数b,c(bc): 3,99 12857 请输入首尾奇数b,c(b
17、c): 2001,2029 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 7 页,共 11 页4114752 42 构建旋转方阵把整数 1,2,. ,n2 从外层至中心按顺时针方向螺旋排列所成的nn 方阵,? 称顺转 n 阶方阵;按逆时针方向螺旋排列所成的称逆转n 阶方阵。1 24 23 22 21 20 19 2 25 40 39 38 37 18 3 26 41 48 47 36 17 4 27 42 49 46 35 16 5 28 43 44 45 34 15 6 29 30 31 32 33 14 7 8 9 10 11 12 13 上
18、图为逆转 7 阶方阵。设计程序选择分别打印逆转10 阶方阵与顺转 15 阶方阵。(1) 设计要点打印二种旋转方阵关键在于数组元素的赋值以及赋值与打印的巧妙结合。对应方阵的 n 行 n 列设置二维数组a(n,n) 。令 m=int(n/2),当 n 为偶数时 ?, 方 阵共 m 圈。 当 n 为 奇 数 时 ,方 阵除 m 圈 外 正 中 间 还 有一 个数a(m+1,m+1)=n*n。对于 m圈,每圈有上下左右四条边。最外圈定义为第1圈, 从外往内依次定义为第 2 圈, . 第 i 圈每边有 n-2i+1 个数。为了实现旋转准确对各圈各边的每一个数组元素赋值,我们引入中间变量s,t: s=n-
19、2i+1 t=t+4s (t置初值 0) 设置 i(1 m)循环对第 i 圈操作 , 设置 j(in-i) 循环对第 i 圈的四条边的n-2i+1 个元素操作。 i,j二重循环可对方阵的每一元素赋值。在顺时针转方阵中 , 具体赋值为 : 上行为 a(i,j)=t+1-i+j:其中 +j体现往右元素值递增1;+t-i体现随圈数 i 增加数值增加值。而1 为具体调整数。右列为 a(j,n+1-i)=t+s+1+j-i,即在 a(i,j)的基础上增 s。下行为 a(n+1-i,j+1)=t+3*s-j+i:其中 -j体现往左元素值递增1;+t+i?体现随圈数 i 增加数值增加值;而3*s 为具体调整
20、数。左列为 a(j+1,i)=t+4*s-j+i,即在 a(n+1-i,j+1)基础上增 s。在逆时针转方阵中,还是上述赋值,只是打印输出时把行列互换。这样处理是巧妙的,较为简便。(2) 程序实现/ 旋转方阵#include 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 8 页,共 11 页#include void main() int i,j,m,n,t,s,z,a2020。 printf( 输入方阵阶 n:) 。 scanf(%d,&n)。 printf( 方阵有以下两种旋转方式:n)。 printf( 1: 逆时针转 2: 顺时针转 n)
21、 。 printf( 选择旋转方式代码 : )。 scanf(%d,&z)。 m=n/2。t=0。 am+1m+1=n*n 。 for(i=1。i=m。i+) / 按规律给 a 数组赋值 s=n+1-2*i。 for(j=i。j=n-i 。j+) aij=t+1-i+j。 ajn+1-i=t+s+1+j-i。 an+1-ij+1=t+3*s-j+i。 aj+1i=t+4*s-j+i。 t=t+4*s。 printf( 所求旋转方阵为 :) 。 for(i=1。i=n 。i+) printf(n)。 for(j=1。j=n 。j+) / 按座标输出方阵 if(z%2=0) printf(%4d,
22、aij)。 else printf(%4d,aji)。 (3) 程序运行示例与变通输入方阵阶 n:7 方阵有以下两种旋转方式: 1: 逆时针转 2: 顺时针转选择旋转方式代码 : 1 所求旋转方阵为: 1 24 23 22 21 20 19 2 25 40 39 38 37 18 3 26 41 48 47 36 17 4 27 42 49 46 35 16 5 28 43 44 45 34 15 6 29 30 31 32 33 14 7 8 9 10 11 12 13 输入方阵阶 n:8 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 9 页,
23、共 11 页方阵有以下两种旋转方式: 1: 逆时针转 2: 顺时针转选择旋转方式代码 : 2 所求旋转方阵为 : 1 2 3 4 5 6 7 8 28 29 30 31 32 33 34 9 27 48 49 50 51 52 35 10 26 47 60 61 62 53 36 11 25 46 59 64 63 54 37 12 24 45 58 57 56 55 38 13 23 44 43 42 41 40 39 14 22 21 20 19 18 17 16 15 程序变通:把程序中的输出量aij 改变为n*n-aij+1,可输出由内到外的旋转方阵。43 n!精确计算定义 n!=1*
24、2*3* *n 输入正整数n(=100), 精确计算并输出n! (若大于10 位时输出其高10位)测试数据:n=30 n=100 44 分数数列老师为了检测学生的观察分析能力与程序设计水平,? 写出一个递推分数数列的前6 项: 1/2, 3/5, 4/7, 6/10, 8/13, 9/15, .,引导学生注意观察数列的构成规律:第i 项的分母 d 与分子 c?存在以下关系 :d=c+i. 而 c 为与前 i-1 项中的所有分子、分母均不相同的最小正整数。试求出该数列的第n 项, 并求出前 n 项中的最大项。测试数据:(1) n=1000 (2) n=2012 45 双和数组把一个偶数 2s 分
25、解为 6 个互不相等的正整数a,b,c,d,e,f,然后把这 6 个精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 10 页,共 11 页正整数分成 (a,b,c)与(d,e,f)两个组,若这两组数具有以下两个相等特性:fedcbafedcba111111则 把 数 组 (a,b,c)与 (d,e,f)称 为 基 于s 的 双 和 数 组 ( 约 定abc,def,ad )。1) 存在双和数组 , s 至少为多大?2) 当 s=98 时有多少个不同的双和数组? 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 11 页,共 11 页