招聘面试程序设计竞赛选拔赛实训.docx

上传人:b****6 文档编号:5402196 上传时间:2022-12-15 格式:DOCX 页数:12 大小:19.77KB
下载 相关 举报
招聘面试程序设计竞赛选拔赛实训.docx_第1页
第1页 / 共12页
招聘面试程序设计竞赛选拔赛实训.docx_第2页
第2页 / 共12页
招聘面试程序设计竞赛选拔赛实训.docx_第3页
第3页 / 共12页
招聘面试程序设计竞赛选拔赛实训.docx_第4页
第4页 / 共12页
招聘面试程序设计竞赛选拔赛实训.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

招聘面试程序设计竞赛选拔赛实训.docx

《招聘面试程序设计竞赛选拔赛实训.docx》由会员分享,可在线阅读,更多相关《招聘面试程序设计竞赛选拔赛实训.docx(12页珍藏版)》请在冰豆网上搜索。

招聘面试程序设计竞赛选拔赛实训.docx

招聘面试程序设计竞赛选拔赛实训

(招聘面试)程序设计竞赛选拔赛(实训)

2011程序设计竞赛选拔赛(实训8)

1、排列数

由1个“1”,2个“2”,k个“3”(1≤k≤6)能组成多少个不同的排列?

输入k,输出排列个数。

k=4,输出:

k=5,输出:

(1)设计要点

注意到1个“1”,2个“2”,k个“3”组成k+3位数,首先通过k+2个10相乘计算k+3位数的起点b=10^(k+2),为枚举提供范围t(b—4*b-1)。

为了检测k+3位数t含有多少个数字1、2、3,每个k+3位整数t赋给d(以保持t不变),然后通过k+3次求余先后分离出t的k+3个数字c:

if(c==1)f++,统计整数t中数字1的个数f;

if(c==2)g++,统计整数t中数字2的个数g;

if(c==3)h++,统计整数t中数字3的个数h。

检测每壹个k+3位整数:

若f=1andg=2andh=k,则应用s进行统计。

最后输出所得排列个数s。

(2)程序设计

//排列数

#include

voidmain()

{intc,f,g,h,i,j,k;

longb,d,s,t;

printf("请输入数字3的个数k(1≤k≤6):

");scanf("%d",&k);

b=1;s=0;

for(i=1;i<=k+2;i++)b=b*10;//计算k+3位数的起点

for(t=b;t<=4*b-1;t++)//枚举首位为3的k+3位数

{d=t;f=0;g=0;h=0;

for(j=1;j<=k+3;j++)

{c=d%10;d=d/10;

if(c==1)f++;//统计数字1的个数

if(c==2)g++;//统计数字2的个数

if(c==3)h++;//统计数字3的个数

}

if(f==1&&g==2&&h==k)s++;//统计个数s

}

printf("s=%ld\n",s);

}

(3)程序运行示例

请输入数字3的个数k(1≤k≤6):

4

s=105

请输入数字3的个数k(1≤k≤6):

5

s=168

(4)拓广

若需求k=100时的排列数,如何求?

1)注意到壹排k个“3”的空位共k+1个。

这k+1个选2个空位共C(k+1,2)种组合,每壹空位放置1个“2”。

这k+1个选1个空位共C(k+1,1)种组合,空位中放置2个“2”。

2)注意到壹排k个“3”和2个“2”的空位共k+3个。

这k+3个选1个空位共C(k+3,1)种组合,空位中放置1个“1”。

3)因而得不同的排列数为:

(C(k+1,2)+C(k+1,1))*C(k+3,1)=(k+1)*(k+2)*(k+3)/2

//排列数

#include

voidmain()

{intk;longs;

printf("请输入数字3的个数k:

");scanf("%d",&k);

s=(k+1)*(k+2)*(k+3)/2;

printf("s=%ld\n",s);

}

请输入数字3的个数k:

100

s=530553

(5)实训1

计算由2个“1”、2个“2”、k个“3”的排列数。

计算由3个“1”、2个“2”、k个“3”的排列数。

测试数据:

k=50

2、求最值

设n为正整数,,式中各项符号为二正壹负。

求当n为多大时,s(n)最接近指定的正整数a?

输入a,输出s(n)最接近a的n,s(n)。

(1)输入1000,输出:

(2)输入2011,输出:

解:

壹般地求当n为多大时,s(n)最接近正整数a?

其中a从键盘输入a。

//s(n)=1+1/(1+1/2)-1/(1+1/2+1/3)+...+1/(1+1/2+...+1/n)

#include

#include

voidmain()

{longa,n,n1;

doublem,ts,s,s1;

printf("请输入a:

");scanf("%d",&a);

n=0;ts=0;s=0;m=100000.0;

while(s

{n=n+1;

ts=ts+(double)1/n;//ts为各项的分母

if(n%3==0)

s=s-1/ts;//求代数和s

else

s=s+1/ts;

if(fabs(s-a)

{m=fabs(s-a);n1=n;s1=s;}

}

printf("n=%ld,s(%d)=%f\n",n1,n1,s1);

}

请输入a:

1000

n=29126,s(29126)=999.959989

请输入a:

2011

n=63376,s(63376)=2011.040087

实训2:

设n为正整数,,式中各项符号为二正壹负,分母符号壹正壹负。

求当n为多大时,s(n)最接近指定的正整数a?

输入a,输出s(n)最接近a的n,s(n)。

测试数据:

a=2011

3、倒立的勾股数

把求勾股数变通为求倒立的勾股数。

定义满足方程式

的正整数x,y,z,称为壹组倒立的勾股数。

试求指定区间[a,b]内的倒立勾股数组。

(1)求指定区间[30,100]内的倒立勾股数组.

(2)求指定区间[100,200]内的倒立勾股数组.

(1)设计要点

显然,倒立勾股数组中x,y不可能相等,且x,y>z。

为避免重复,不妨设x>y>z。

于指定区间[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)求区间内倒立勾股数程序设计

//求指定区间内倒立勾股数组

#include

#include

voidmain()

{inta,b,n;longx,y,z;

printf("求指定区间[a,b]内倒立的勾股数组.");

printf("\n请输入区间[a,b]的上下限a,b:

");

scanf("%d,%d",&a,&b);

printf("\n区间[%d,%d]中倒立的勾股数组有:

\n",a,b);

n=0;

for(z=a;z<=b-2;z++)

for(y=z+1;y<=b-1;y++)

for(x=y+1;x<=b;x++)

if(z*z*(x*x+y*y)==x*x*y*y)//满足倒立勾股数条件时输出

{n++;

printf("1/%ld^2+1/%ld^2=1/%ld^2\n",x,y,z);

}

printf("共%d组勾股数.",n);

}

(3)程序运行示例

区间[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组勾股数.

4、双和数组

寻求6个互不相等的正整数a,b,c,d,e,f且分成(a,b,c)和(d,e,f)俩个组,若这俩组数具有以下俩个相等特性:

则把数组(a,b,c)和(d,e,f)称为双和数组(约定a

1)设a+b+c=d+e+f=s,存于双和数组,s至少为多大?

2)当s=98时有多少个不同的双和数组?

(1)求解要点

从键盘输入整数s,因6个不同正整数之和至少为21,即输入整数s≥11。

设置a,b和d,e循环。

注意到a+b+c=s,且a

a:

1——(s-3)/3。

因b比a至少大1,c比a至少大2。

b:

a+1——(s-a-1)/2。

因c比b至少大1。

c=s-a=b。

设置d,e循环基本同上,只是d>a,因而d起点为a+1。

把比较倒数和相等1/a+1/b+1/c=1/d+1/e+1/f转化为比较整数相等

d*e*f*(b*c+c*a+a*b)=a*b*c*(e*f+f*d+d*e)(*)

若上式不成立,即倒数和不相等,则返回。

同时注意到俩个3元组中若部分相同部分不同,不能有倒数和相等,因而可省略排除之上6个正整数中是否存于相等的检测。

若式(*)成立,打印输出和为s的双和数组,且用x统计解的个数。

(2)C程序设计

//双和数组探索

#include

#include

voidmain()

{inta,b,c,d,e,f,x,s;

for(s=21;s<=100;s++)

{printf("s=%d:

\n",s);

x=0;

for(a=1;a<=(s-3)/3;a++)

for(b=a+1;b<=(s-a-1)/2;b++)

for(d=a+1;d<=(s-3)/3;d++)

for(e=d+1;e<=(s-d-1)/2;e++)

{c=s-a-b;f=s-d-e;

if(a*b*c*(e*f+f*d+d*e)!

=d*e*f*(b*c+c*a+a*b))

continue;//排除倒数和不相等

x++;

printf("%3d:

(%2d,%2d,%2d)",x,a,b,c);

printf("(%2d,%2d,%2d)\n",d,e,f);

}

if(x==0)printf("无解!

\n");

}

}

(3)程序运行结果和讨论

s=26:

1:

(4,10,12)(5,6,15)

s=98:

1:

(2,36,60)(3,5,90)

2:

(7,28,63)(8,18,72)

3:

(7,35,56)(8,20,70)

4:

(10,33,55)(12,20,66)

(4)实训3

寻求6个互不相等的正整数a,b,c,d,e,f且分成(a,b,c)和(d,e,f)俩个组,若这俩组数具有以下俩个相等特性:

则把数组(a,b,c)和(d,e,f)称为和积数组(约定a

1)设a+b+c=d+e+f=s,存于和积数组,s至少为多大?

2)当s=89时有多少个不同的和积数组?

5、m位完美平方数

用0,1,2,...,9能组成多少个没有重复数字的m(1

输入m,输出没有重复数字的m位平方数的个数,且输出其中最大的。

m=7,输出:

m=10,输出:

//用0,1,2,...,9组成没有重复数字的m位平方数

#include

#include

voidmain()

{intk,m,n,t,f[10];

doublea,b,c,d,w,x,a1,d1;

printf("请确定整数m:

");scanf("%d",&m);

x=1.0;

for(k=2;k<=m;k++)x=x*10;//确定m位数的起点x

n=0;

b=(int)pow(x,0.5);c=pow(10*x-1,0.5);

for(a=b+1;a<=c;a++)

{d=a*a;w=d;//确保d为m位平方数

for(k=0;k<=9;k++)f[k]=0;

while(w>0)

{t=(int)fmod(w,10);f[t]=f[t]+1;w=floor(w/10);}

for(t=0,k=0;k<=9;k++)

if(f[k]>1){t=1;break;}//测试平方数是否有重复数字

if(t==0)//测试平方数中没有重复数字

{n++;d1=d;a1=a;}

}

printf("共可组成%d个没有重复数字的%d位平方数.",n,m);

printf("其中最大的为:

%.0f=%.0f^2\n",d1,a1);

}

请确定整数m:

7

共可组成123个没有重复数字的7位平方数.其中最大的为:

9872164=3142^2

请确定整数m:

10

共可组成87个没有重复数字的10位平方数.其中最大的为:

9814072356=99066^2

实训4:

用0,1,2,...,9能组成没有重复数字的m(1

问:

(1)求s(10),即求出没有重复数字的10位平方数的个数。

(2)当m为多大时,没有重复数字的m位平方数个数s(m)最大?

6、最小01串积

程序设计爱好者A,B进行计算游戏:

B任给壹个正整数b,A寻求另壹个整数a,使a和b的积最小且全为0和1组成的数。

例如,B给出整数24,A寻求整数a:

4625,使得a*b的最小01串积为:

111000

输入b,输出a和最小01串积。

b=24,输出:

b=2011,输出:

(1)对a枚举

考虑到a和积d可能大于10位,用双精度型。

对a递增枚举,检测积d=a*b是否为01串

//01串积对a枚举

#include

#include

voidmain()

{longc,t;doublea,b,d,j;

printf("B给出整数b:

");scanf("%lf",&b);

a=1;

while

(1)

{a++;d=a*b;

j=d;t=0;

while(j>0)//分离积的各个数字c

{c=(int)fmod(j,10);j=floor(j/10);

if(c>1){t=1;break;}//检测是否含有0,1以外的数字

}

if(t==0)

{printf("A寻求整数a:

%.0f:

\n",a);

printf("a*b的最小01串积为:

%.0f\n",d);

break;

}

}

}

B给出整数b:

73

A寻求整数a:

137:

a*b的最小01串积为:

10001

B给出整数b:

54

A寻求整数a:

203909465:

a*b的最小01串积为:

11011111110

(2)二进制枚举,应用余数判别。

1)注意到01串积为十进制数,应用求余运算“%”可分别求得个位“1”,十位“1”,…,分别除以已给b的余数,存放于c数组中:

c

(1)为1,c

(2)为10除以b的余数,c(3)为100除以b的余数,…。

2)要从小到大搜索01串,不重复也不遗漏,从中找出最小的能被b整除01串积。

为此,设置k从1开始递增,把k转化为二进制,就得到所需要的这些串。

不过,这时每个串不再见作二进制数,而要见作十进制数。

3)于某壹k转化为二进制数过程中,每转化壹位a(i)(0或1),求出该位除以b的余数a(i)*c(i),通过累加求和得k转化的整个二进制数除以b的余数s。

4)判别余数s是否被b整除:

若s%b=0,即找到所求最小的01串积。

a从高位开始除以b的商存储于d数组,实施整数除法运算:

x=e*10+a[j];//e为上轮余数,x为被除数

d[j]=x/b;//d为a从高位开始除以b的商

e=x%b;//e为试商余数

去掉d数组的高位“0”后,输出d即为所寻求的数。

最后从高位开始打印a数组,即为01串积。

(3)程序设计

//01串积二进制枚举

#include

voidmain()

{intb,e,i,j,t,x,a[2000],d[2000],c[2000];

longk,s;

printf("B给出整数b:

");scanf("%d",&b);

c[1]=1;

for(i=2;i<200;i++)

c[i]=10*c[i-1]%b;//c(i)为右边第i位1除以b的余数

k=1;

while

(1)

{k++;j=k;i=0;s=0;

while(j>0)

{i++;a[i]=j%2;

s+=a[i]*c[i];j=j/2;s=s%b;//除2取余法转化为二进制

}

if(s%b==0)

{for(e=0,j=i;j>=1;j--)

{x=e*10+a[j];

d[j]=x/b;e=x%b;//a从高位开始除以b的商为d

}

j=i;

while(d[j]==0)j--;//去掉d数组的高位"0"

printf("A寻求整数a:

");

for(t=j;t>=1;t--)

printf("%d",d[t]);

printf("\na*b的最小01串积为:

");

for(t=i;t>=1;t--)

printf("%d",a[t]);

printf("\n");

break;

}

}

}

(4)程序运行示例

B给出整数b:

54,A寻求整数a:

203909465

a*b的最小01串积为:

11011111110

B给出整数b:

2011,A寻求整数a:

4977628101

a*b的最小01串积为:

10010010111111

(5)实训5

1)任给壹个正整数b,寻求另壹个整数a,使a和b的积最小且全为0和5组成的数。

2)任给壹个正整数b,寻求另壹个整数a,使a和b的积最小且全为2和5组成的数。

3)任给壹个正整数b,寻求另壹个整数a,使a和b的积最小且全为0、1、2组成的数。

测试数据:

b=54;b=2011

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 党团工作 > 思想汇报心得体会

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1