蓝桥杯省赛赛前集训题共14题.docx

上传人:b****4 文档编号:3669367 上传时间:2022-11-24 格式:DOCX 页数:37 大小:190.92KB
下载 相关 举报
蓝桥杯省赛赛前集训题共14题.docx_第1页
第1页 / 共37页
蓝桥杯省赛赛前集训题共14题.docx_第2页
第2页 / 共37页
蓝桥杯省赛赛前集训题共14题.docx_第3页
第3页 / 共37页
蓝桥杯省赛赛前集训题共14题.docx_第4页
第4页 / 共37页
蓝桥杯省赛赛前集训题共14题.docx_第5页
第5页 / 共37页
点击查看更多>>
下载资源
资源描述

蓝桥杯省赛赛前集训题共14题.docx

《蓝桥杯省赛赛前集训题共14题.docx》由会员分享,可在线阅读,更多相关《蓝桥杯省赛赛前集训题共14题.docx(37页珍藏版)》请在冰豆网上搜索。

蓝桥杯省赛赛前集训题共14题.docx

蓝桥杯省赛赛前集训题共14题

第1题:

星系炸弹(2015年省赛C/C++B组第2题)

在X星系的广袤空间中漂浮着许多X星人造“炸弹”,用来作为宇宙中的路标。

每个炸弹都可以设定多少天之后爆炸。

比如:

阿尔法炸弹2015年1月1日放置,定时为15天,则它在2015年1月16日爆炸。

有一个贝塔炸弹,2014年11月9日放置,定时为1000天,请你计算它爆炸的准确日期。

请填写该日期,格式为yyyy-mm-dd即4位年份2位月份2位日期。

比如:

2015-02-19

请严格按照格式书写。

不能出现其它文字或符号。

•结果:

2017-08-05

•解决方法:

用Excel拖

这个题会了的同学们把上课讲过的,课件上的,其他几道Excel拖动题都做一遍。

 

第2题:

(2015年校选拔赛C/C++B组第3题)

 

如果x的x次幂结果为10(参见【图1.png】),你能计算出x的近似值吗?

显然,这个值是介于2和3之间的一个数字。

请把x的值计算到小数后6位(四舍五入),并填写这个小数值。

注意:

只填写一个小数,不要写任何多余的符号或说明。

#include

#include

#include

usingnamespacestd;

intmain()

{

doublex;

for(x=2;x<=3;x+=1e-7)

{

if(abs(pow(x,x)-10)<1e-6)

cout<

}

return0;

}

 

答案:

2.506184

其他类似题:

ALGO-23一元三次方程求解

 

第3题(全排列)

注意:

全排列必考!

全排列必考!

全排列必考!

重要的事要说三遍!

白打酒(2014年省赛本科B组第3题)

话说大诗人白,一生好饮。

幸好他从不开车。

  一天,他提着酒壶,从家里出来,酒壶中有酒2斗。

他边走边唱:

  无事街上走,提壶去打酒。

  逢店加一倍,遇花喝一斗。

  这一路上,他一共遇到店5次,遇到花10次,已知最后一次遇到的是花,他正好把酒喝光了。

 

  请你计算白遇到店和花的次序,可以把遇店记为a,遇花记为b。

则:

babaabbabbabbbb就是合理的次序。

像这样的答案一共有多少呢?

请你计算出所有可能方案的个数(包含题目给出的)。

答案:

14

 

解法1:

next_permutation的解法

#include

#include

usingnamespacestd;

intmain()

{

intp[15]={1,1,1,1,1,2,2,2,2,2,2,2,2,2,2};//1是店,2是花

intsum,cnt=0;

do

{

sum=2;

for(inti=0;i<15;i++)

if(p[i]==1)

sum<<=1;

elseif(p[i]==2)

sum--;

if(sum==0)t++;

}

while(next_permutation(p,p+14));//因为最后一次遇到的肯定是花,所以只排前14个数,不排最后一个

cout<

return0;

}

解法2:

交换大法解法

#include

usingnamespacestd;

#defineN14//因为最后一次肯定是花,所以只排14个数

intt;

boolok(intp[],intbegin,intend)

{

for(inti=begin;i

if(p[i]==p[end])

returnfalse;

returntrue;

}

voidperms(intp[],intstart)

{

inti;

if(start==N-1)

{

intsum=2;

for(i=0;i

if(p[i]==1)

sum<<=1;

elseif(p[i]==2)

sum--;

if(sum==1)t++;//倒数第2次,剩1斗酒

return;

}

for(i=start;i

{

if(ok(p,start,i))

{

swap(p[start],p[i]);

perms(p,start+1);

swap(p[start],p[i]);

}

}

}

intmain()

{

intp[]={1,1,1,1,1,2,2,2,2,2,2,2,2,2};//1是店,2是花

perms(p,0);

cout<

return0;

}

解法3:

字符串全排列的解法

#include

#include

usingnamespacestd;

intmain()

{

strings="aaaaabbbbbbbbb";//a是店,b是花

intsum,cnt=0;

do

{

sum=2;

for(inti=0;i<15;i++)

if(s[i]=='a')

sum<<=1;

elseif(s[i]=='b')

sum--;

if(sum==1)t++;

}

while(next_permutation(s.begin(),s.end()));

cout<

return0;

}

解法4:

递归解法

#include

usingnamespacestd;

intt=0;

voidf(inta,intb,intc)//a个店,b朵花,c升酒

{

if(a>5||b>9)return;

f(a+1,b,c*2);

f(a,b+1,c-1);

if(a==5&&b==9&&c==1)

cnt++;

}

intmain()

{

f(0,0,2);

cout<

}

 

第4题(逻辑推理题)

练习系统ADV-143扶老奶奶过街

•一共有5个红领巾,编号分别为A、B、C、D、E,老奶奶被他们其中一个扶过了马路。

  五个红领巾各自说话:

  A:

我和E都没有扶老奶奶

  B:

老奶奶是被C和E其中一个扶过大街的

  C:

老奶奶是被我和D其中一个扶过大街的

  D:

B和C都没有扶老奶奶过街

  E:

我没有扶老奶奶

  已知五个红领巾中有且只有2个人说的是真话,请问是谁扶这老奶奶过了街?

  若有多个答案,在一行中输出,编号之间用空格隔开

  例如

  ABCDE(这显然不是正确答案)

解法1--位运算

#include

usingnamespacestd;

#defineN5

intmain()

{

inti,j,t,a[N];

for(i=0x10;i>0;i>>=1)

{

t=i;

for(j=N-1;j>=0;j--)

{

a[j]=t&1;

t>>=1;

}

//ABCDE5个变量存5个人的真假话状态,1为真话,0为假话

intA=(a[0]+a[4]==0);//A:

我和E都没有扶老奶奶

intB=(a[2]+a[4]==1);//B:

老奶奶是被C和E其中一个扶过大街的

intC=(a[2]+a[3]==1);//C:

老奶奶是被我和D其中一个扶过大街的

intD=(a[1]+a[2]==0);//D:

B和C都没有扶老奶奶过街

intE=(a[4]==0);//E:

我没有扶老奶奶

if(A+B+C+D+E==2)//5个人有且只有2个人说的是真话

{

for(j=0;j

{

if(a[j])cout<

}

}

}

return0;

}

解法2-全排列

#include

#include

usingnamespacestd;

#defineN5

intmain()

{

inta[N]={1,0,0,0,0};//1扶了。

0没扶。

do

{

//ABCDE5个变量存5个人的真假话状态,1为真话,0为假话

intA=(a[0]+a[4]==0);//A:

我和E都没有扶老奶奶

intB=(a[2]+a[4]==1);//B:

老奶奶是被C和E其中一个扶过大街的

intC=(a[2]+a[3]==1);//C:

老奶奶是被我和D其中一个扶过大街的

intD=(a[1]+a[2]==0);//D:

B和C都没有扶老奶奶过街

intE=(a[4]==0);//E:

我没有扶老奶奶

if(A+B+C+D+E==2)//5个人有且只有2个人说的是真话

{

for(inti=0;i

{

if(a[i])cout<

}

}

}

while(prev_permutation(a,a+N));

return0;

}

解法3-递归(大材小用了)

#include

usingnamespacestd;

#defineN5

inta[N];//1扶了。

0没扶。

voidf(intk)

{

inti;

if(k==N)

{

intsum=0;

for(i=0;i

sum+=a[i];

if(sum==1)//只有一个人扶了

{

//ABCDE5个变量存5个人的真假话状态,1为真话,0为假话

intA=(a[0]+a[4]==0);//A:

我和E都没有扶老奶奶

intB=(a[2]+a[4]==1);//B:

老奶奶是被C和E其中一个扶过大街的

intC=(a[2]+a[3]==1);//C:

老奶奶是被我和D其中一个扶过大街的

intD=(a[1]+a[2]==0);//D:

B和C都没有扶老奶奶过街

intE=(a[4]==0);//E:

我没有扶老奶奶

if(A+B+C+D+E==2)//5个人有且只有2个人说的是真话

{

for(i=0;i

{

if(a[i])cout<

}

}

}

return;

}

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

{

a[k]=i;

f(k+1);

}

}

intmain()

{

f(0);

return0;

}

第5题:

牌型种数(2015年省赛C/C++B组第7题)

•小明被劫持到X赌城,被迫与其他3人玩牌。

•一副扑克牌(去掉大小王牌,共52),均匀发给4个人,每个人13。

•这时,小明脑子里突然冒出一个问题:

•如果不考虑花色,只考虑点数,也不考虑自己得到的牌的先后顺序,自己手里能拿到的初始牌型组合一共有多少种呢?

答案:

3598180

解法1:

暴力法,比较慢,5秒左右出答案,但不容易出错

#include

usingnamespacestd;

intmain()

{

inta1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13;//13种点数

intt=0;

for(a1=0;a1<=4;a1++)

for(a2=0;a2<=4;a2++)

for(a3=0;a3<=4;a3++)

for(a4=0;a4<=4;a4++)

for(a5=0;a5<=4;a5++)

for(a6=0;a6<=4;a6++)

for(a7=0;a7<=4;a7++)

for(a8=0;a8<=4;a8++)

for(a9=0;a9<=4;a9++)

for(a10=0;a10<=4;a10++)

for(a11=0;a11<=4;a11++)

for(a12=0;a12<=4;a12++)

for(a13=0;a13<=4;a13++)

{

if(a1+a2+a3+a4+a5+a6+a7+a8+a9+a10+a11+a12+a13==13)

cnt++;

}

cout<

return0;

}

解法2:

DFS+剪枝,秒杀

#include

usingnamespacestd;

intt=0;

voidf(intsum,intn)

{

inti;

if(sum>13||(13-n)*4+sum<13||n>13)return;//剪枝

if(sum==13)

{

cnt++;

return;

}

for(i=0;i<=4;i++)

{

f(sum+i,n+1);

}

}

intmain()

{

f(0,0);

cout<

return0;

}

 

第6题:

单位分数(组合问题)

(2015年校选拔赛C/C++B组第6题)

•形如:

1/a的分数称为单位分数。

•可以把1分解为若干个互不相同的单位分数之和。

•例如:

•1=1/2+1/3+1/9+1/18

•1=1/2+1/3+1/10+1/15

•1=1/3+1/5+1/7+1/9+1/11+1/15+1/35+1/45+1/231

•等等,类似这样的分解无穷无尽。

•我们增加一个约束条件:

最大的分母必须不超过30

•请你求出分解为n项时的所有不同分解法。

•数据格式要求:

•输入一个整数n,表示要分解为n项(n<12)

•输出分解后的单位分数项,中间用一个空格分开。

•每种分解法占用一行,行间的顺序按照分母从小到大排序。

•例如,

•输入:

•4

•程序应该输出:

•1/21/31/81/24

•1/21/31/91/18

•1/21/31/101/15

•1/21/41/51/20

•1/21/41/61/12

•再例如,

•输入:

•5

•程序应该输出:

•1/21/31/121/211/28

•1/21/41/61/211/28

•1/21/41/71/141/28

•1/21/41/81/121/24

•1/21/41/91/121/18

•1/21/41/101/121/15

•1/21/51/61/121/20

•1/31/41/51/61/20

•资源约定:

•峰值存消耗<256M

•CPU消耗<2000ms

 

题目分析:

题目有点坑。

题意说不超过30,那理应可以等于30的,但是当n=5时,1/21/31/121/201/30也应该是正确的。

可是…,题目给的答案却没有这个解,所以,不能等于30

注意一定要剪枝,不剪的话会超过2000ms,剪枝之后大约428ms

#include

#include

usingnamespacestd;

inta[11];//n<12

intn;

voidC(intbegin,intm,doublesum)//从begin开始,选n个数中的第m个,已选出的数的和是sum

{

inti;

if(m1)//剪枝,很重要,不剪的话会超过2000ms

{

return;

}

if(m==n)

{

if(abs(sum-1)<1e-9)

{

for(i=0;i

{

cout<<"1/"<

if(i!

=n-1)

{

cout<<'';

}

}

cout<

}

return;

}

for(i=begin;i<30;i++)

{

a[m]=i;

C(i+1,m+1,sum+1.0/i);

}

}

intmain()

{

cin>>n;

C(2,0,0);//从2开始,选n个数中的第0个,已选出的数的和是0

return0;

}

 

第7题(背包问题)

练习系统ALGO-115算法训练和为T

#include

usingnamespacestd;

longlonga[100];

intflag[100];

longlongT;

intn;

intt;

boolok()

{

for(inti=0;i

{

if(flag[i]==1)

returntrue;

}

returnfalse;

}

voidf(intk,longlongsum)

{

if(k==n)

{

if(ok()&&sum==T)

{

for(inti=n-1;i>=0;i--)

{

if(flag[i])

{

cout<

}

}

cout<

cnt++;

}

return;

}

flag[k]=0;

f(k+1,sum);

flag[k]=1;

f(k+1,sum+a[k]);

}

intmain()

{

inti;

cin>>n;

for(i=n-1;i>=0;i--)

{

cin>>a[i];

}

cin>>T;

f(0,0);

cout<

return0;

}

 

第8题(高精度整数和浮点数)

两个题,分别用Java的BigInteger和BigDecimal来做。

因为只求最后结果,如果用C/C++很麻烦,而用JAVABigInteger和BigDecimal来做很简单,所以不论C/C++还是JAVA组,都要学会以下两道题的JAVA解法。

1.梅森素数(6分)2013预赛JavaA组第3题

如果一个数字的所有真因子之和等于自身,则称它为“完全数”或“完美数”

例如:

6=1+2+3

28=1+2+4+7+14

早在公元前300多年,欧几里得就给出了判定完全数的定理:

若2^n-1是素数,则2^(n-1)*(2^n-1)是完全数。

其中^表示“乘方”运算,乘方的优先级比四则运算高,例如:

2^3=8,2*2^3=16,2^3-1=7

但人们很快发现,当n很大时,判定一个大数是否为素数到今天也依然是个难题。

因为法国数学家梅森的猜想,我们习惯上把形如:

2^n-1的素数称为:

梅森素数。

截止2013年2月,一共只找到了48个梅森素数。

新近找到的梅森素数太大,以至于难于用一般的编程思路窥其全貌,所以我们把任务的难度降低一点:

1963年,美国伊利诺伊大学为了纪念他们找到的第23个梅森素数n=11213,在每个寄出的信封上都印上了“2^11213-1是素数”的字样。

2^11213-1这个数字已经很大(有3000多位),请你编程求出这个素数的十进制表示的最后100位。

答案:

2191

2.黄金连分数(2013省赛题)

importjava.math.BigDecimal;

publicclassMain

{

publicstaticvoidmain(String[]args)

{

BigDecimalb=BigDecimal.ONE;

for(inti=0;i<500;i++)

{

b=b.add(BigDecimal.ONE);

b=BigDecimal.ONE.divide(b,101,BigDecimal.ROUND_HALF_UP);

}

System.out.println(b.setScale(100,BigDecimal.ROUND_HALF_UP));

}

}

 

第9题(进制转换)

1.十进制转十六进制(递归),练习系统-基础练习-BASIC-10

问题描述

  十六进制数是在程序设计时经常要使用到的一种整数的表示方式。

它有0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F共16个符号,分别表示十进制数的0至15。

十六进制的计数方法是满16进1,所以十进制数16在十六进制中是10,而十进制的17在十六进制中是11,以此类推,十进制的30在十六进制中是1E。

  给出一个非负整数,将它表示成十六进制的形式。

输入格式

  输入包含一个非负整数a,表示要转换的数。

0<=a<=2147483647

输出格式

  输出这个整数的16进制表示

样例输入

30

样例输出

1E

#include

usingnamespacestd;

strings="0123456789ABCDEF";

voidf(intn)

{

if(n>=16)f(n>>4);

cout<

}

intmain()

{

intn;

cin>>n;

f(n);

return0;

}

 

2.//十六进制转十进制//练习系统-基础练习-BASIC-11

问题描述

  从键盘输入一个不超过8位的正的十六进制数字符串,将它转换为正的十进制数后输出。

  注:

十六进制数中的10~15分别用大写的英文字母A、B、C、D、E、F表示。

样例输入

FFFF

样例输出

65535

#include

usingnamespacestd;

intmain()

{

inti,t;

unsignedsum=0;

strings;

cin>>s;

for(i=0;s[i];i++)

{

t=s[i]<='9'?

s[i]-'

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

当前位置:首页 > 教学研究 > 教学反思汇报

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

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