程序设计大赛题目解答.docx
《程序设计大赛题目解答.docx》由会员分享,可在线阅读,更多相关《程序设计大赛题目解答.docx(38页珍藏版)》请在冰豆网上搜索。
程序设计大赛题目解答
1.求代数和
设n为正整数,求和
式中各项符号为二正一负,分母符号为一正一负。
正整数n从键盘输入,输出和s四舍五入精确到小数点后5位。
输入n=100输出:
输入n=2011输出:
//求代数和
#include
voidmain()
{longj,n;
doublets,s;
printf("请输入n:
");
scanf("%d",&n);
j=0;ts=0;s=0;
while(j{j=j+1;if(j%2==0)ts=ts-(double)1/j;//ts为各项的分母elsets=ts+(double)1/j;if(j%3==0)s=s-sqrt(j)/ts;//求代数和selses=s+sqrt(j)/ts;}printf("s=%.5f\n",s);} 请输入n:100s=324.74013请输入n:2011s=28924.48725 变通:设2#include#includevoidmain(){intn,n1=1;doublesum1=1,sum2=1,g;printf("请输入n:");scanf("%d",&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;elsesum1+=g/sum2;}printf("%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枚举求解#includevoidmain(){intk,m;longa,j,n,f[1000];printf("计算不大于n的项数,请指定n:");scanf("%ld",&n);printf("输出序列的第m项,请指定m:");scanf("%d",&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]赋值}printf("幂序列中不大于%ld的项数为:%d\n",n,k);if(m<=k)printf("从小到大排序的第%d项为:%ld\n",m,f[m]);elseprintf("所输序号m大于序列的项数!\n");}(3)程序运行示例n=10000,m=50输出:67,2304n=10000000,m=100输出: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= #includevoidmain(){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;}while(n>=2){i=n/3;sum+=i;n=i+n%3;if(n==2){sum++;break;}}printf("%d\n",sum);} 原题:有这样一道智力题:“某商店规定:三个空汽水瓶可以换一瓶汽水。小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?”答案是5瓶,方法如下:先用9个空瓶子换3瓶汽水,喝掉3瓶满的,喝完以后4个空瓶子,用3个再换一瓶,喝掉这瓶满的,这时候剩2个空瓶子。然后你让老板先借给你一瓶汽水,喝掉这瓶满的,喝完以后用3个空瓶子换一瓶满的还给老板。如果小张手上有n个空汽水瓶,最多可以换多少瓶汽水喝? //规定3个空瓶可换回1瓶汽水。开始有n个空瓶,最多可喝多少瓶汽水?#includevoidmain(){longn,m,t,x;printf("请输入开始拥有的空瓶数n:");scanf("%ld",&n);t=n;m=0;//确定初始值while(t>=3){x=t/3;m=m+x;//用3x个空瓶换回x瓶汽水t=t-2*x;//空瓶数减少2x个printf("用其中%ld个空瓶换回%ld瓶汽水。",3*x,x);printf("喝完后空瓶个数变为%ld.\n",t);}if(t==2){m=m+1;printf("借1瓶汽水,再还3空瓶,两清.\n");}printf("答案:开始有%ld个空瓶,可喝%ld瓶汽水。\n",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瓶汽水。问最多可喝多少瓶汽水?#includevoidmain(){longk,n,t,x;printf("请输入n:");scanf("%ld",&n);k=n*100/48;t=k;//k为汽水瓶数,t为空瓶数printf("有%ld元钱,可买回%ld瓶汽水。",n,k);if(n*100>k*48)printf("尚余%ld分钱。",n*100-k*48);printf("\n喝完%ld瓶汽水后,空瓶按以下方案换回汽水:\n",k);while(t>=20){x=t/20;k=k+7*x;//用20x个空瓶换回7x瓶汽水t=t-13*x;//空瓶数减少13x个printf("用其中%ld个空瓶换回%ld瓶汽水。",20*x,7*x);printf("喝完后空瓶个数变为%ld.\n",t);}if(t>=13){k=k+7;t=t-13;printf("借7瓶汽水,再还20空瓶,空瓶个数变为%ld.\n",t);}while(t>=3){x=t/3;k=k+x;//用3x个空瓶换回x瓶汽水t=t-2*x;//空瓶数减少2x个printf("用其中%ld个空瓶换回%ld瓶汽水。",3*x,x);printf("喝完后空瓶个数变为%ld.\n",t);}if(t==2){k=k+1;printf("借1瓶汽水,再还3空瓶.\n");}printf("答案:有%ld元钱,最多可喝%ld瓶汽水。\n",n,k);}请输入n:100有100元钱,可买回208瓶汽水。尚余16分钱。喝完208瓶汽水后,空瓶按以下方案换回汽水:用其中200个空瓶换回70瓶汽水。喝完后空瓶个数变为78.用其中60个空瓶换回21瓶汽水。喝完后空瓶个数变为39.用其中20个空瓶换回7瓶汽水。喝完后空瓶个数变为26.用其中20个空瓶换回7瓶汽水。喝完后空瓶个数变为13.借7瓶汽水,再还20空瓶,空瓶个数变为0.答案:有100元钱,最多可喝320瓶汽水。 请输入n:2011有2011元钱,可买回4189瓶汽水。尚余28分钱。喝完4189瓶汽水后,空瓶按以下方案换回汽水:用其中4180个空瓶换回1463瓶汽水。喝完后空瓶个数变为147用其中1460个空瓶换回511瓶汽水。喝完后空瓶个数变为523.用其中520个空瓶换回182瓶汽水。喝完后空瓶个数变为185.用其中180个空瓶换回63瓶汽水。喝完后空瓶个数变为68.用其中60个空瓶换回21瓶汽水。喝完后空瓶个数变为29.用其中20个空瓶换回7瓶汽水。喝完后空瓶个数变为16.借7瓶汽水,再还20空瓶,空瓶个数变为3.用其中3个空瓶换回1瓶汽水。喝完后空瓶个数变为1.答案:有2011元钱,最多可喝6444瓶汽水。 省去过程,简化设计://规定1瓶汽水48分钱,今有n元钱;规定3个空瓶可换回1瓶汽水,//或20个空瓶可换回7瓶汽水。问最多可喝多少瓶汽水?#includevoidmain(){longk,n,t,x;printf("请输入n:");scanf("%ld",&n);k=n*100/48;t=k;//k为汽水瓶数,t为空瓶数x=t/13;k=k+7*x;//实现1空瓶=7/13瓶汽水t=t-13*x;//空瓶数减少13x个x=t/2;k=k+x;//实现1空瓶=1/2瓶汽水printf("答案:%ld元钱最多可喝%ld瓶汽水。\n",n,k);} 请输入n:100答案:100元钱最多可喝320瓶汽水。 请输入n:2011答案: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#include#includevoidmain(){doublea,m,n,x,y;printf("解PELL方程:x^2-ny^2=1.\n");printf("请输入非平方整数n:");scanf("%lf",&n);m=floor(sqrt(n+1));if(m*m==n){printf("n为平方数,方程无正整数解!\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",n);printf("x=%.0f,y=%.0f\n",x,y);break;}}if(y>10000000)printf("未求出该方程的基本解!");}4.程序运行示例与说明解PELL方程:x^2-ny^2=1.请输入非平方整数n: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>0&&t%7>0&&g==0,s2作相应统计。 (2)程序设计//统计含数字7且不能被7整除的m位整数的个数s1,其中不含数字4的个数s2#includevoidmain(){intc,f,g,i,j,m;longb,d,s1,s2,t;printf("请输入位数m(2<=m<=9):");scanf("%d",&m);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<=m;j++){c=d%10;d=d/10;if(c==7)f++;//统计数字7的个数if(c==4)g++;//统计数字4的个数}if(f>0&&t%7>0)s1++;//统计含数字7且不能被7整除数的个数if(f>0&&t%7>0&&g==0)s2++;//统计其中不含数字4的个数}printf("s1=%ld,s2=%ld\n",s1,s2);}(3)程序运行示例请输入位数m(2<=k<=9):5s1=32152,s2=20412 请输入位数m(2<=k<=9):6s1=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);(2)程序设计//斜折对称方阵#include#includevoidmain(){inti,j,m,n,a[30][30];printf("请确定方阵阶数(奇数)n:");scanf("%d",&n);if(n%2==0){printf("请输入奇数!");return;}m=(n+1)/2;for(i=1;i<=n;i++)for(j=1;j<=n;j++){if(i<=m&&j<=m||i>m&&j>m)a[i][j]=abs(i-j);//方阵左上部与右下部元素赋值if(i<=m&&j>m||i>m&&j<=m)a[i][j]=abs(i+j-n-1);//方阵右上部与左下部元素赋值}printf("%d阶对称方阵为:\n",n);for(i=1;i<=n;i++){for(j=1;j<=n;j++)//输出对称方阵printf("%3d",a[i][j]);printf("\n");}} 运行以上两个程序,可以在欣赏各个具体的对称方阵中,感受从特例到一般的神奇。 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) 原题:在平面直角坐标系下,台球桌是一个左下角在(0,0),右上角在(L,W)的矩形。有一个球心在(x,y),半径为R的圆形母球放在台球桌上(整个球都在台球桌内)。受撞击后,球沿极角为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应四舍五入保留两位小数。 样例输入样例输出100100801059022311010070105180199990000000080.0056.0071.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
{j=j+1;
if(j%2==0)
ts=ts-(double)1/j;//ts为各项的分母
else
ts=ts+(double)1/j;
if(j%3==0)
s=s-sqrt(j)/ts;//求代数和s
s=s+sqrt(j)/ts;
}
printf("s=%.5f\n",s);
请输入n:
100s=324.74013
2011s=28924.48725
变通:
设2#include#includevoidmain(){intn,n1=1;doublesum1=1,sum2=1,g;printf("请输入n:");scanf("%d",&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;elsesum1+=g/sum2;}printf("%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枚举求解#includevoidmain(){intk,m;longa,j,n,f[1000];printf("计算不大于n的项数,请指定n:");scanf("%ld",&n);printf("输出序列的第m项,请指定m:");scanf("%d",&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]赋值}printf("幂序列中不大于%ld的项数为:%d\n",n,k);if(m<=k)printf("从小到大排序的第%d项为:%ld\n",m,f[m]);elseprintf("所输序号m大于序列的项数!\n");}(3)程序运行示例n=10000,m=50输出:67,2304n=10000000,m=100输出: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= #includevoidmain(){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;}while(n>=2){i=n/3;sum+=i;n=i+n%3;if(n==2){sum++;break;}}printf("%d\n",sum);} 原题:有这样一道智力题:“某商店规定:三个空汽水瓶可以换一瓶汽水。小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?”答案是5瓶,方法如下:先用9个空瓶子换3瓶汽水,喝掉3瓶满的,喝完以后4个空瓶子,用3个再换一瓶,喝掉这瓶满的,这时候剩2个空瓶子。然后你让老板先借给你一瓶汽水,喝掉这瓶满的,喝完以后用3个空瓶子换一瓶满的还给老板。如果小张手上有n个空汽水瓶,最多可以换多少瓶汽水喝? //规定3个空瓶可换回1瓶汽水。开始有n个空瓶,最多可喝多少瓶汽水?#includevoidmain(){longn,m,t,x;printf("请输入开始拥有的空瓶数n:");scanf("%ld",&n);t=n;m=0;//确定初始值while(t>=3){x=t/3;m=m+x;//用3x个空瓶换回x瓶汽水t=t-2*x;//空瓶数减少2x个printf("用其中%ld个空瓶换回%ld瓶汽水。",3*x,x);printf("喝完后空瓶个数变为%ld.\n",t);}if(t==2){m=m+1;printf("借1瓶汽水,再还3空瓶,两清.\n");}printf("答案:开始有%ld个空瓶,可喝%ld瓶汽水。\n",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瓶汽水。问最多可喝多少瓶汽水?#includevoidmain(){longk,n,t,x;printf("请输入n:");scanf("%ld",&n);k=n*100/48;t=k;//k为汽水瓶数,t为空瓶数printf("有%ld元钱,可买回%ld瓶汽水。",n,k);if(n*100>k*48)printf("尚余%ld分钱。",n*100-k*48);printf("\n喝完%ld瓶汽水后,空瓶按以下方案换回汽水:\n",k);while(t>=20){x=t/20;k=k+7*x;//用20x个空瓶换回7x瓶汽水t=t-13*x;//空瓶数减少13x个printf("用其中%ld个空瓶换回%ld瓶汽水。",20*x,7*x);printf("喝完后空瓶个数变为%ld.\n",t);}if(t>=13){k=k+7;t=t-13;printf("借7瓶汽水,再还20空瓶,空瓶个数变为%ld.\n",t);}while(t>=3){x=t/3;k=k+x;//用3x个空瓶换回x瓶汽水t=t-2*x;//空瓶数减少2x个printf("用其中%ld个空瓶换回%ld瓶汽水。",3*x,x);printf("喝完后空瓶个数变为%ld.\n",t);}if(t==2){k=k+1;printf("借1瓶汽水,再还3空瓶.\n");}printf("答案:有%ld元钱,最多可喝%ld瓶汽水。\n",n,k);}请输入n:100有100元钱,可买回208瓶汽水。尚余16分钱。喝完208瓶汽水后,空瓶按以下方案换回汽水:用其中200个空瓶换回70瓶汽水。喝完后空瓶个数变为78.用其中60个空瓶换回21瓶汽水。喝完后空瓶个数变为39.用其中20个空瓶换回7瓶汽水。喝完后空瓶个数变为26.用其中20个空瓶换回7瓶汽水。喝完后空瓶个数变为13.借7瓶汽水,再还20空瓶,空瓶个数变为0.答案:有100元钱,最多可喝320瓶汽水。 请输入n:2011有2011元钱,可买回4189瓶汽水。尚余28分钱。喝完4189瓶汽水后,空瓶按以下方案换回汽水:用其中4180个空瓶换回1463瓶汽水。喝完后空瓶个数变为147用其中1460个空瓶换回511瓶汽水。喝完后空瓶个数变为523.用其中520个空瓶换回182瓶汽水。喝完后空瓶个数变为185.用其中180个空瓶换回63瓶汽水。喝完后空瓶个数变为68.用其中60个空瓶换回21瓶汽水。喝完后空瓶个数变为29.用其中20个空瓶换回7瓶汽水。喝完后空瓶个数变为16.借7瓶汽水,再还20空瓶,空瓶个数变为3.用其中3个空瓶换回1瓶汽水。喝完后空瓶个数变为1.答案:有2011元钱,最多可喝6444瓶汽水。 省去过程,简化设计://规定1瓶汽水48分钱,今有n元钱;规定3个空瓶可换回1瓶汽水,//或20个空瓶可换回7瓶汽水。问最多可喝多少瓶汽水?#includevoidmain(){longk,n,t,x;printf("请输入n:");scanf("%ld",&n);k=n*100/48;t=k;//k为汽水瓶数,t为空瓶数x=t/13;k=k+7*x;//实现1空瓶=7/13瓶汽水t=t-13*x;//空瓶数减少13x个x=t/2;k=k+x;//实现1空瓶=1/2瓶汽水printf("答案:%ld元钱最多可喝%ld瓶汽水。\n",n,k);} 请输入n:100答案:100元钱最多可喝320瓶汽水。 请输入n:2011答案: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#include#includevoidmain(){doublea,m,n,x,y;printf("解PELL方程:x^2-ny^2=1.\n");printf("请输入非平方整数n:");scanf("%lf",&n);m=floor(sqrt(n+1));if(m*m==n){printf("n为平方数,方程无正整数解!\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",n);printf("x=%.0f,y=%.0f\n",x,y);break;}}if(y>10000000)printf("未求出该方程的基本解!");}4.程序运行示例与说明解PELL方程:x^2-ny^2=1.请输入非平方整数n: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>0&&t%7>0&&g==0,s2作相应统计。 (2)程序设计//统计含数字7且不能被7整除的m位整数的个数s1,其中不含数字4的个数s2#includevoidmain(){intc,f,g,i,j,m;longb,d,s1,s2,t;printf("请输入位数m(2<=m<=9):");scanf("%d",&m);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<=m;j++){c=d%10;d=d/10;if(c==7)f++;//统计数字7的个数if(c==4)g++;//统计数字4的个数}if(f>0&&t%7>0)s1++;//统计含数字7且不能被7整除数的个数if(f>0&&t%7>0&&g==0)s2++;//统计其中不含数字4的个数}printf("s1=%ld,s2=%ld\n",s1,s2);}(3)程序运行示例请输入位数m(2<=k<=9):5s1=32152,s2=20412 请输入位数m(2<=k<=9):6s1=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);(2)程序设计//斜折对称方阵#include#includevoidmain(){inti,j,m,n,a[30][30];printf("请确定方阵阶数(奇数)n:");scanf("%d",&n);if(n%2==0){printf("请输入奇数!");return;}m=(n+1)/2;for(i=1;i<=n;i++)for(j=1;j<=n;j++){if(i<=m&&j<=m||i>m&&j>m)a[i][j]=abs(i-j);//方阵左上部与右下部元素赋值if(i<=m&&j>m||i>m&&j<=m)a[i][j]=abs(i+j-n-1);//方阵右上部与左下部元素赋值}printf("%d阶对称方阵为:\n",n);for(i=1;i<=n;i++){for(j=1;j<=n;j++)//输出对称方阵printf("%3d",a[i][j]);printf("\n");}} 运行以上两个程序,可以在欣赏各个具体的对称方阵中,感受从特例到一般的神奇。 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) 原题:在平面直角坐标系下,台球桌是一个左下角在(0,0),右上角在(L,W)的矩形。有一个球心在(x,y),半径为R的圆形母球放在台球桌上(整个球都在台球桌内)。受撞击后,球沿极角为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应四舍五入保留两位小数。 样例输入样例输出100100801059022311010070105180199990000000080.0056.0071.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
{
intn,n1=1;
doublesum1=1,sum2=1,g;
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;elsesum1+=g/sum2;}printf("%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枚举求解#includevoidmain(){intk,m;longa,j,n,f[1000];printf("计算不大于n的项数,请指定n:");scanf("%ld",&n);printf("输出序列的第m项,请指定m:");scanf("%d",&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]赋值}printf("幂序列中不大于%ld的项数为:%d\n",n,k);if(m<=k)printf("从小到大排序的第%d项为:%ld\n",m,f[m]);elseprintf("所输序号m大于序列的项数!\n");}(3)程序运行示例n=10000,m=50输出:67,2304n=10000000,m=100输出: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= #includevoidmain(){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;}while(n>=2){i=n/3;sum+=i;n=i+n%3;if(n==2){sum++;break;}}printf("%d\n",sum);} 原题:有这样一道智力题:“某商店规定:三个空汽水瓶可以换一瓶汽水。小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?”答案是5瓶,方法如下:先用9个空瓶子换3瓶汽水,喝掉3瓶满的,喝完以后4个空瓶子,用3个再换一瓶,喝掉这瓶满的,这时候剩2个空瓶子。然后你让老板先借给你一瓶汽水,喝掉这瓶满的,喝完以后用3个空瓶子换一瓶满的还给老板。如果小张手上有n个空汽水瓶,最多可以换多少瓶汽水喝? //规定3个空瓶可换回1瓶汽水。开始有n个空瓶,最多可喝多少瓶汽水?#includevoidmain(){longn,m,t,x;printf("请输入开始拥有的空瓶数n:");scanf("%ld",&n);t=n;m=0;//确定初始值while(t>=3){x=t/3;m=m+x;//用3x个空瓶换回x瓶汽水t=t-2*x;//空瓶数减少2x个printf("用其中%ld个空瓶换回%ld瓶汽水。",3*x,x);printf("喝完后空瓶个数变为%ld.\n",t);}if(t==2){m=m+1;printf("借1瓶汽水,再还3空瓶,两清.\n");}printf("答案:开始有%ld个空瓶,可喝%ld瓶汽水。\n",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瓶汽水。问最多可喝多少瓶汽水?#includevoidmain(){longk,n,t,x;printf("请输入n:");scanf("%ld",&n);k=n*100/48;t=k;//k为汽水瓶数,t为空瓶数printf("有%ld元钱,可买回%ld瓶汽水。",n,k);if(n*100>k*48)printf("尚余%ld分钱。",n*100-k*48);printf("\n喝完%ld瓶汽水后,空瓶按以下方案换回汽水:\n",k);while(t>=20){x=t/20;k=k+7*x;//用20x个空瓶换回7x瓶汽水t=t-13*x;//空瓶数减少13x个printf("用其中%ld个空瓶换回%ld瓶汽水。",20*x,7*x);printf("喝完后空瓶个数变为%ld.\n",t);}if(t>=13){k=k+7;t=t-13;printf("借7瓶汽水,再还20空瓶,空瓶个数变为%ld.\n",t);}while(t>=3){x=t/3;k=k+x;//用3x个空瓶换回x瓶汽水t=t-2*x;//空瓶数减少2x个printf("用其中%ld个空瓶换回%ld瓶汽水。",3*x,x);printf("喝完后空瓶个数变为%ld.\n",t);}if(t==2){k=k+1;printf("借1瓶汽水,再还3空瓶.\n");}printf("答案:有%ld元钱,最多可喝%ld瓶汽水。\n",n,k);}请输入n:100有100元钱,可买回208瓶汽水。尚余16分钱。喝完208瓶汽水后,空瓶按以下方案换回汽水:用其中200个空瓶换回70瓶汽水。喝完后空瓶个数变为78.用其中60个空瓶换回21瓶汽水。喝完后空瓶个数变为39.用其中20个空瓶换回7瓶汽水。喝完后空瓶个数变为26.用其中20个空瓶换回7瓶汽水。喝完后空瓶个数变为13.借7瓶汽水,再还20空瓶,空瓶个数变为0.答案:有100元钱,最多可喝320瓶汽水。 请输入n:2011有2011元钱,可买回4189瓶汽水。尚余28分钱。喝完4189瓶汽水后,空瓶按以下方案换回汽水:用其中4180个空瓶换回1463瓶汽水。喝完后空瓶个数变为147用其中1460个空瓶换回511瓶汽水。喝完后空瓶个数变为523.用其中520个空瓶换回182瓶汽水。喝完后空瓶个数变为185.用其中180个空瓶换回63瓶汽水。喝完后空瓶个数变为68.用其中60个空瓶换回21瓶汽水。喝完后空瓶个数变为29.用其中20个空瓶换回7瓶汽水。喝完后空瓶个数变为16.借7瓶汽水,再还20空瓶,空瓶个数变为3.用其中3个空瓶换回1瓶汽水。喝完后空瓶个数变为1.答案:有2011元钱,最多可喝6444瓶汽水。 省去过程,简化设计://规定1瓶汽水48分钱,今有n元钱;规定3个空瓶可换回1瓶汽水,//或20个空瓶可换回7瓶汽水。问最多可喝多少瓶汽水?#includevoidmain(){longk,n,t,x;printf("请输入n:");scanf("%ld",&n);k=n*100/48;t=k;//k为汽水瓶数,t为空瓶数x=t/13;k=k+7*x;//实现1空瓶=7/13瓶汽水t=t-13*x;//空瓶数减少13x个x=t/2;k=k+x;//实现1空瓶=1/2瓶汽水printf("答案:%ld元钱最多可喝%ld瓶汽水。\n",n,k);} 请输入n:100答案:100元钱最多可喝320瓶汽水。 请输入n:2011答案: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#include#includevoidmain(){doublea,m,n,x,y;printf("解PELL方程:x^2-ny^2=1.\n");printf("请输入非平方整数n:");scanf("%lf",&n);m=floor(sqrt(n+1));if(m*m==n){printf("n为平方数,方程无正整数解!\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",n);printf("x=%.0f,y=%.0f\n",x,y);break;}}if(y>10000000)printf("未求出该方程的基本解!");}4.程序运行示例与说明解PELL方程:x^2-ny^2=1.请输入非平方整数n: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>0&&t%7>0&&g==0,s2作相应统计。 (2)程序设计//统计含数字7且不能被7整除的m位整数的个数s1,其中不含数字4的个数s2#includevoidmain(){intc,f,g,i,j,m;longb,d,s1,s2,t;printf("请输入位数m(2<=m<=9):");scanf("%d",&m);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<=m;j++){c=d%10;d=d/10;if(c==7)f++;//统计数字7的个数if(c==4)g++;//统计数字4的个数}if(f>0&&t%7>0)s1++;//统计含数字7且不能被7整除数的个数if(f>0&&t%7>0&&g==0)s2++;//统计其中不含数字4的个数}printf("s1=%ld,s2=%ld\n",s1,s2);}(3)程序运行示例请输入位数m(2<=k<=9):5s1=32152,s2=20412 请输入位数m(2<=k<=9):6s1=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);(2)程序设计//斜折对称方阵#include#includevoidmain(){inti,j,m,n,a[30][30];printf("请确定方阵阶数(奇数)n:");scanf("%d",&n);if(n%2==0){printf("请输入奇数!");return;}m=(n+1)/2;for(i=1;i<=n;i++)for(j=1;j<=n;j++){if(i<=m&&j<=m||i>m&&j>m)a[i][j]=abs(i-j);//方阵左上部与右下部元素赋值if(i<=m&&j>m||i>m&&j<=m)a[i][j]=abs(i+j-n-1);//方阵右上部与左下部元素赋值}printf("%d阶对称方阵为:\n",n);for(i=1;i<=n;i++){for(j=1;j<=n;j++)//输出对称方阵printf("%3d",a[i][j]);printf("\n");}} 运行以上两个程序,可以在欣赏各个具体的对称方阵中,感受从特例到一般的神奇。 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) 原题:在平面直角坐标系下,台球桌是一个左下角在(0,0),右上角在(L,W)的矩形。有一个球心在(x,y),半径为R的圆形母球放在台球桌上(整个球都在台球桌内)。受撞击后,球沿极角为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应四舍五入保留两位小数。 样例输入样例输出100100801059022311010070105180199990000000080.0056.0071.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
n1++;
if(n1%2==0)
sum2+=-(double)1/n1;
elsesum2+=(double)1/n1;
g=sqrt(n1);
if(n1%3==0)
sum1+=-g/sum2;
sum1+=g/sum2;
printf("%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];
printf("计算不大于n的项数,请指定n:
scanf("%ld",&n);
printf("输出序列的第m项,请指定m:
scanf("%d",&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]赋值
printf("幂序列中不大于%ld的项数为:
%d\n",n,k);
if(m<=k)
printf("从小到大排序的第%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;
while(n>=2)
i=n/3;
sum+=i;
n=i+n%3;
if(n==2)
sum++;break;
printf("%d\n",sum);
原题:
有这样一道智力题:
“某商店规定:
三个空汽水瓶可以换一瓶汽水。
小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?
”答案是5瓶,方法如下:
先用9个空瓶子换3瓶汽水,喝掉3瓶满的,喝完以后4个空瓶子,用3个再换一瓶,喝掉这瓶满的,这时候剩2个空瓶子。
如果小张手上有n个空汽水瓶,最多可以换多少瓶汽水喝?
//规定3个空瓶可换回1瓶汽水。
开始有n个空瓶,最多可喝多少瓶汽水?
{longn,m,t,x;
printf("请输入开始拥有的空瓶数n:
");scanf("%ld",&n);
t=n;m=0;//确定初始值
while(t>=3)
{x=t/3;m=m+x;//用3x个空瓶换回x瓶汽水
t=t-2*x;//空瓶数减少2x个
printf("用其中%ld个空瓶换回%ld瓶汽水。
",3*x,x);
printf("喝完后空瓶个数变为%ld.\n",t);
if(t==2)
{m=m+1;
printf("借1瓶汽水,再还3空瓶,两清.\n");
printf("答案:
开始有%ld个空瓶,可喝%ld瓶汽水。
\n",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;
printf("请输入n:
k=n*100/48;t=k;//k为汽水瓶数,t为空瓶数
printf("有%ld元钱,可买回%ld瓶汽水。
",n,k);
if(n*100>k*48)printf("尚余%ld分钱。
",n*100-k*48);
printf("\n喝完%ld瓶汽水后,空瓶按以下方案换回汽水:
\n",k);
while(t>=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;
printf("借7瓶汽水,再还20空瓶,空瓶个数变为%ld.\n",t);
{x=t/3;k=k+x;//用3x个空瓶换回x瓶汽水
{k=k+1;
printf("借1瓶汽水,再还3空瓶.\n");
有%ld元钱,最多可喝%ld瓶汽水。
\n",n,k);
请输入n:
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;k=k+7*x;//实现1空瓶=7/13瓶汽水
x=t/2;k=k+x;//实现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;
printf("解PELL方程:
x^2-ny^2=1.\n");
printf("请输入非平方整数n:
scanf("%lf",&n);
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",n);
printf("x=%.0f,y=%.0f\n",x,y);
break;
if(y>10000000)
printf("未求出该方程的基本解!
4.程序运行示例与说明
解PELL方程:
x^2-ny^2=1.
请输入非平方整数n:
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,输出:
首先通过乘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>0&&t%7>0&&g==0,s2作相应统计。
(2)程序设计
//统计含数字7且不能被7整除的m位整数的个数s1,其中不含数字4的个数s2
{intc,f,g,i,j,m;
longb,d,s1,s2,t;
printf("请输入位数m(2<=m<=9):
");scanf("%d",&m);
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<=m;j++)
{c=d%10;d=d/10;
if(c==7)f++;//统计数字7的个数
if(c==4)g++;//统计数字4的个数
if(f>0&&t%7>0)s1++;//统计含数字7且不能被7整除数的个数
if(f>0&&t%7>0&&g==0)s2++;//统计其中不含数字4的个数
printf("s1=%ld,s2=%ld\n",s1,s2);
请输入位数m(2<=k<=9):
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];
printf("请确定方阵阶数(奇数)n:
");scanf("%d",&n);
if(n%2==0)
{printf("请输入奇数!
");return;}
m=(n+1)/2;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{if(i<=m&&j<=m||i>m&&j>m)
a[i][j]=abs(i-j);//方阵左上部与右下部元素赋值
if(i<=m&&j>m||i>m&&j<=m)
a[i][j]=abs(i+j-n-1);//方阵右上部与左下部元素赋值
printf("%d阶对称方阵为:
{for(j=1;j<=n;j++)//输出对称方阵
printf("%3d",a[i][j]);
printf("\n");
运行以上两个程序,可以在欣赏各个具体的对称方阵中,感受从特例到一般的神奇。
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
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1