分享
分享赚钱 收藏 举报 版权申诉 / 16

类型程序设计竞赛题解、思考与变通.doc

  • 上传人:buyk185
  • 文档编号:6175869
  • 上传时间:2019-03-31
  • 格式:DOC
  • 页数:16
  • 大小:145KB
  • 配套讲稿:

    如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。

    特殊限制:

    部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。

    关 键  词:
    程序设计竞赛题解、思考与变通.doc
    资源描述:

    1、程序设计竞赛题解、思考与变通(2014 湖南理工学院程序设计竞赛评析)1旅馆开关门旅馆里有 10000 间房间,从 1 到 10000 编了号。第一位服务员把所有的房间门都打开了,第二位服务员把所有编号是 2 的倍数的房间进行“相反处理” ,第三位服务员把所有编号是 3 的倍数的房间作“相反处理” , 第n(1void main() int j,k,n,s,a10001;printf(“ 请输入正整数 n(nvoid main() int j,k,n,s,km,min,a10001;printf(“ 请输入正整数 n(nvoid main() long n;printf(“ 请输入正整数 n:

    2、 “);scanf(“%ld“, / 输入 nprintf(“%ldn“,n/2); / 输出结果变通:某学院有 m 个学生参加南湖春游,休息时喝汽水。南湖商家公告:买 1 瓶汽水定价 1.40 元,喝 1 瓶汽水(瓶不带走)1 元。为节约资源,规定 3 个空瓶可换回 1 瓶汽水,或 20 个空瓶可换回 7 瓶汽水。(3) 为方面顾客,可先借后还。例如借 1 瓶汽水,还 3 个空瓶;或借 7 瓶汽水,还 20 个空瓶。问 m 个学生每人喝 1 瓶汽水(瓶不带走) ,至少需多少元?输入正整数 m(2#includevoid main() int a,c,k,m,d101; char n101;s

    3、canf(“%s“,n); / 以字符串方式输入长整数for(m=0,k=0;nk!=0;k+) m+; / m 统计输入的整数 n 的位数dk=nk-48; / 把数字字符变为数值c=d0; / c 为余数for(k=1;kvoid main() int a,c,p,n;printf(“ 请输入 p: “);scanf(“%d“,c=1111;n=4; / 变量 c 与 n 赋初值 while(c!=0) / 循环模拟整数竖式除法 a=c*10+1;c=a%p;n=n+1; / 每试商一位 n 增 1 printf(“ 由 %d 个 1 组成的整数能被 %d 整除。n“,n,p);思考:对指

    4、定的正整数 p,如何寻求最小的 01 串积?4解不等式设 n 为正整数,解不等式(1/2/13/213/41/2/na b 分母中各项符号“+” 、 “-”相间)输入正整数 a,b(1#includevoid main() long c,d,i; double a,b,t,ts,s;printf(“ 请输入 a,b: “);scanf(“%lf %lf“,i=0;t=ts=s=0;while(sm 时退出循环,d=k+1, 可得区间解:nd.因 s(d+1)m,显然 s(d)m;而 n=d+2 时 1.0/(n+3)为“+” ,可得 s(d+2)m;以后各项中, “-”项小于其前面的“+”项,

    5、可知对于 nd+2 有 s(n)m 成立。(2)在 nvoid main() long d,m,k; double s;printf(“ 请输入 m: “); scanf(“%d“,k=-2;s=0;while(s0) s=s+1.0/k; / 逐项累加求和else s=s-1.0/k;if(sm) printf(“ n=%ld,“,k); / 逐个输出离散解 printf(“ n=%ld n“,d); / 最后输出区间解3. 算法测试与思考请输入 m: 4n=10151, n=10153, n=10154注意:要特别注意,不要把前面的离散解遗失。思考:如果把后一个离散解写入区间解中?能否简化

    6、逐项求和找出离散解?4. 枚举改进(1) 每三项一组(包含二正一负)累加求和:s=s+1.0/k+1.0/(k+1)-1.0/(k+2); (k=1,4,)若累加到某一组时 sm 时退出循环,d=k+1, 可得区间解:nd.此时,s(d-1)有可能大于 m.为得到 s(d-1),在原 s(d+1)基础上实施-1.0/d+1.0/(d+1)得 s(d-1):若 s(d-1)m,合并得区间解:nd-1;若 s(d-1)m 时,s(d-3)还有可能大于 m.因而在上 s(d-1)的基础上实施 s+1.0/(d-2)-1.0/(d-1),得 s(d-3):若 s(d-3)m, 得一个离散解:nd-3;

    7、若 s(d-3)void main() long d,k,t,m; double s;printf(“n 请输入 m: “); scanf(“%d“,k=-2;s=0;while(sm) t=d-1; else t=d; / 得区间解 nts=s+1.0/(d-2)-1.0/(d-1); / 得 s(d-3)if(sm) printf(“ n=%ld,“,d-3); / 输出一个离散解printf(“ n%ld n“,t); / 输出区间解(5) 算法测试与分析原枚举设计与改进后的枚举设计的时间复杂度都是 O(n),深入分析可知改进后枚举所需时间只有原枚举时间的 1/4。5拆分为连续正整数之和

    8、一个正整数有可能可以被表示为 n(n=2)个连续正整数之和,如:15=1+2+3+4+515=4+5+6请输入 m: 7n=82273511, n8227351315=7+8请编写程序,根据输入的任何一个正整数 n,找出符合这种要求的所有连续正整数序列的个数 C。 如:对于 15,其输出结果是 3:对于 16,其输出结果是:0。设计 1:基本设计定义变量 s 求和,设计 i(1(n-1)/2)循环作为连续求和的起始项,j(1(n+1)/2)循环作为连续求和的累加项。每加一项后检验:若 s=n,则统计并输出一个连续序列“ij”后退出求和的 j 循环。若不等,则继续求和。/ 基本设计程序 1 #i

    9、nclude void main() long c,i,j,n,s;printf(“ 请输入和数 n:“);scanf(“%ld“,c=0;for(i=1;ivoid main() long c,i,j,n,s;printf(“ 请输入和数 n:“);scanf(“%ld“,c=0;for(i=1;i=n)if(s=n)c+;printf(“ %d: %d+.+%dn“,c,i,j);break;printf(“ 共有以上%d 个解。n“,c); / 输出拆分种数 c 3. 优化设计设满足题意的连续正整数的个数最大为 t,由1+2+t=t(t+1)/2=n显然有 tsqrt(2*n),可取 t

    10、=sqrt(2*n)。同时设起始数为 m 的连续 k 项之和为 n,即有(21)(1)(1)mk解出 m 得2nk建立关于连续正整数个数 k(2t)循环,在循环中检验:如果 2n 不能被 k 整除,或 2n/k-k+1 不能被 2 整除,则返回;否则得整数m=(2n/k+1-k)/2,即为一个解:m+(m+k-1) 。/ 优化设计程序 3 #include #include void main() long c,k,m,n,t;printf(“ 请输入和数 n:“);scanf(“%ld“,t=sqrt(2*n);c=0;for(k=2;k0 | (2*n/k+1-k)%20) continu

    11、e;m=(2*n/k+1-k)/2;c+;printf(“ %d: %d+.+%dn“,c,m,m+k-1); printf(“ 共有以上%d 个解。n“,c); / 输出种数 c 数据测试:请输入和数 n:20151: 1007+.+10082: 401+.+4053: 197+.+2064: 149+.+1615: 65+.+906: 50+.+807: 2+.+63共有以上 7 个解。以上 3 个程序的时间复杂度分析:程序 1 为 O(n2)。程序 2 的 j 循环平均值估值为 n(1/2),因而其时间复杂度为 O(n(3/2)。程序 3 的循环次数 t 为 n(1/2),因而其时间复杂

    12、度为 O(n(1/2)。变通:把“连续”去掉!本节所探讨的整数拆分与上一章的整数划分都是把一个整数(和数)分解为若干个数(零数)之和,所不同的是:整数划分允许零数重复,而拆分不允许零数重复。整数划分未指定零数的范围(默认所有不大于和数的正整数) ,而本节探讨的整数拆分需指定零数的范围。(1) 问题提出给定正整数 s(简称为和数) ,把 s 折分成为连续整数 1m(ms) (简称为零数或部分)之和,拆分式中不允许零数重复,且不记零数的次序。例如,把 s=9 折分成为连续整数 15 的拆分式为:9= 4+ 5;9= 1+ 3+ 5;9= 2+ 3+ 4。共 3 个。输入正整数 s,m(ms),试求

    13、 s 共有多少个不同的拆分式?并展示出 s 的所有这些拆分式。递归算法设计要点我们在以上实现组合的基础上求解拆分式。注意到拆分与式中各零数的排列顺序无关,我们考虑从连续整数 1m 这 m个数中取 w(wvoid main()/ 和数 s,零数取自 1-m #include int k,w,n,m,s,a100; void main() int i,h,wmin,wmax;int c(int k);printf(“ 请输入和数,最大零数:“);scanf(“%d,%d“,for(h=0,i=1;is) wmax=i-1;break;if(im) / 输入的最大零数太小,程序返回 printf(“

    14、 输入的最大零数太小!n“);return; for(h=0,i=m;i=1;i-) h=h+i;if(hs) wmin=m-i;break;for(w=wmin;w0;j-)t=t+aj;if(t=s) / 满足条件时输出一个拆分式 n+;printf(“%d=“,s); for(j=1;jvoid main() int i,j,k,n,x; double y;printf(“ 请输入整数 n,x:“);scanf(“%d %d“,k=0;for(i=1;i#include void main() int i,j,m,n,z,p73;long b,c,d,k,s,t; double y; p

    15、rintf(“ 请输入整数 n,m: “); scanf(“%d %d“, for(i=1;in) z=1;break; / 数字超范围退出 s=s+c; / 统计数字和 if(z=0 / 统计个数 y=(double)k;for(j=1;jvoid main()int a,d,n,r,i,j,k,t,u,c200,b200;printf(“input n,d:“);scanf(“%d,%d“,a=n/d;c1=n%d;printf(“ %d/%d=“,n,d);if(a!=0) printf(“%d“,a); / 输出整数部分 printf(“.“);for(k=1;k=d;k+)a=ck*

    16、10;bk=a/d;ck+1=a%d;u=0; / 实施试商 if(ck+1=0) / 余数为零,打印小数 for(i=1;i=k;i+) printf(“%d“,bi);break;for(j=1;j=k;j+)if(ck+1=cj) / 余数相同,有循环节 for(t=1;tj;t+) printf(“%d“,bt); / 打印循环节前的小数 printf(“(“);r=k-j+1;for(t=j;t=k;t+) printf(“%d“,bt); / 打印循环节 printf(“)。“); printf(“n 循环节共%d 位。“,r);u=1;break;if(u=1) break;(3)程序运行示例input n,d:83,9283/92=.90(2173913043478260869565)。循环节共 22 位。input n,d:11,5911/59=.(1864406779661016949152542372881355932203389830508474576271)。循环节共 58 位。

    展开阅读全文
    提示  道客多多所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
    关于本文
    本文标题:程序设计竞赛题解、思考与变通.doc
    链接地址:https://www.docduoduo.com/p-6175869.html
    关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

    道客多多用户QQ群:832276834  微博官方号:道客多多官方   知乎号:道客多多

    Copyright© 2025 道客多多 docduoduo.com 网站版权所有世界地图

    经营许可证编号:粤ICP备2021046453号    营业执照商标

    1.png 2.png 3.png 4.png 5.png 6.png 7.png 8.png 9.png 10.png



    收起
    展开