历年蓝桥杯省赛B组真题试题.docx
《历年蓝桥杯省赛B组真题试题.docx》由会员分享,可在线阅读,更多相关《历年蓝桥杯省赛B组真题试题.docx(20页珍藏版)》请在冰豆网上搜索。
历年蓝桥杯省赛B组真题试题
历年蓝桥杯省赛B组真题试题
Lt
D
〔1〕
煤球数目
有一堆煤球,堆成三角棱锥形。
具体:
第一层放1个,
第二层3个〔排列成三角形〕,
第三层6个〔排列成三角形〕,
第四层10个〔排列成三角形〕,
....
如果一共有100层,共有多少个煤球?
题解:
纯粹的数学题而已
inta[101]={0};
for(inti=1;i<101;i++)
a[i]=a[i-1]+i;
intans=0;
for(intj=1;j<101;j++)
ans+=a[j];
printf("%d\n",ans);
〔2〕
生日蜡烛
某君从某年开始每年都举办一次生日party,并且每次都要吹熄与年龄相同根数的蜡烛。
现在算起来,他一共吹熄了236根蜡烛。
请问,他从多少岁开始过生日party的?
请填写他开始过生日party的年龄数。
题解:
暴力枚举。
第一重循环枚举刚开始过生日时候的岁数。
第二重循环是枚举现在的岁数
第三重循环就是将刚开始过生日的岁数和现在的岁数加起来。
intstart,end;
for(start=1;start<236;start++)
{
for(end=start;end<236;end++)
{
intsum=0;
for(inti=start;i<=end;i++)
sum+=i;
if(sum==236)
printf("start:
%dend:
%d\n",start,end);
}
}
〔3〕
BDEF
A+—+——=10
CGHI
〔如果显示有问题,可以参见【图1.jpg】〕
这个算式中A~I代表1~9的数字,不同的字母代表不同的数字。
比方:
6+8/3+952/714就是一种解法,
5+3/1+972/486是另一种解法。
这个算式一共有多少种解法?
//29
题解:
DFS+回溯
由于计算机中5/2会等于2,而且如果打算采用精度方面的处理的话,会很麻烦,而且很容易错。
所以,把这些式子全部变成乘法形式就好了。
A*C*GHI+B*GHI+DEF*C=10*C*GHI
代码:
intvisit[10],num[10];
intsum=0;
voiddfs(intn)
{
if(n==10)
{
intb=num[7]*100+num[8]*10+num[9];//GHI
inta=num[4]*100+num[5]*10+num[6];//DEF
//cout<
if(num[1]*num[3]*b+num[2]*b+num[3]*a==10*num[3]*b)sum++;
//cout<<"*"<return;
}
for(inti=1;i<=9;++i)
{
if(!
visit[i])
{
visit[i]=1;
num[n]=i;
dfs(n+1);
visit[i]=0;
num[n]=0;
}
}
}
intmain()
{
memset(num,0,sizeof(num));
memset(visit,0,sizeof(visit));
dfs
(1);
cout<return0;
}
〔4〕
快速排序
排序在各种场合经常被用到。
快速排序是十分常用的高效率的算法。
其思想是:
先选一个“标尺〞,
用它把整个队列过一遍筛子,
以保证:
其左边的元素都不大于它,其右边的元素都不小于它。
这样,排序问题就被分割为两个子区间。
再分别对子区间排序就可以了。
这样,排序问题就被分割为两个子区间。
再分别对子区间排序就可以了。
下面的代码是一种实现,请分析并填写划线局部缺少的代码。
#include
voidswap(inta[],inti,intj)
{
intt=a[i];
a[i]=a[j];
a[j]=t;
}
intpartition(inta[],intp,intr)
{
inti=p;
intj=r+1;
intx=a[p];
while
(1)
{
while(iwhile(a[--j]>x);//一样的,一直左移直到小于x时
if(i>=j)break;//如果一直移动到了相交的区间,说明这个区间内都是由小到大的,就直接退拉!
不用交换啦!
swap(a,i,j);//有的话呢,就交换,这样保证了左小右大。
}
______________________;
returnj;
}
voidquicksort(inta[],intp,intr)
{
if(p{
intq=partition(a,p,r);
quicksort(a,p,q-1);
quicksort(a,q+1,r);
}
}
intmain()
{
inti;
inta[]={5,13,6,24,2,8,19,27,6,12,1,17};
intN=12;
quicksort(a,0,N-1);
for(i=0;iprintf("\n");
return0;
}
题解:
快速排序。
这里是单步快排。
就是将一堆数按照某个数作为基准数分成左右两堆
swap(a,p,j),因为这时候的j是已经不大于了x的,p这个位置要放该区间的最小值,j满足,换过去。
〔5〕
抽签
X星球要派出一个5人组成的观察团前往W星。
其中:
A国最多可以派出4人。
B国最多可以派出2人。
C国最多可以派出2人。
....
那么最终派往W星的观察团会有多少种国别的不同组合呢?
下面的程序解决了这个问题。
数组a[]中既是每个国家可以派出的最多的名额。
程序执行结果为:
DEFFF
CEFFF
CDFFF
CDEFF
CCFFF
CCEFF
CCDFF
CCDEF
BEFFF
BDFFF
BDEFF
BCFFF
BCEFF
BCDFF
BCDEF
....
(以下省略,总共101行)
#include
#defineN6
#defineM5
#defineBUF1024
voidf(inta[],intk,intm,charb[])
{
inti,j;
if(k==N)
{
b[M]=0;
if(m==0)printf("%s\n",b);
return;
}
for(i=0;i<=a[k];i++)
{
for(j=0;j
______________________;//填空位置
}
}
intmain()
{
inta[N]={4,2,2,1,1,3};
charb[BUF];
f(a,0,M,b);
return0;
}
仔细阅读代码,填写划线局部缺少的内容。
注意:
不要填写任何已有内容或说明性文字。
题解:
这个题目是这样的,对于f(inta[],intk,intm,charb[])。
a[]是每个国家的最多指派人数,k表示当前是哪个国家,m表示还需要派送几个人(可以为负数).b表示已经派送的人的字符串。
所以这个题目在递归中间的的第一个循环表示从0~a[i]中让i国选择指派人数,内循环只是向b[]记录的过程。
所以答案是f(a,k+1,m-i,b).因为这里i=j.应该f(a,k+1,m-j,b)也可以。
〔6〕
方格填数
如下的10个格子
〔如果显示有问题,也可以参看【图1.jpg】〕
填入0~9的数字。
要求:
连续的两个数字不能相邻。
〔左右、上下、对角都算相邻〕
一共有多少种可能的填数方案?
请填写表示方案数目的整数。
注意:
你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
题解:
1580
深搜+回溯,填完之后在判断是否可以。
#include
#include
int flag[3][4]; //表示哪些可以填数
int mpt[3][4]; //填数
bool visit[10];
int ans = 0;
void init() //初始化
{
int i,j;
for(i = 0 ; i < 3 ; i ++)
for(j = 0 ; j < 4 ; j ++)
flag[i][j] = 1;
flag[0][0] = 0;
flag[2][3] = 0;
}
void Solve()
{
int dir[8][2] = { 0,1,0,-1,1,0,-1,0,1,1,1,-1,-1,1,-1,-1};
int book = true;
for(int i = 0 ; i < 3 ; i ++)
{
for(int j = 0 ; j < 4; j ++)
{
//判断每个数周围是否满足
if(flag[i][j] == 0)continue;
for( int k = 0 ; k < 8 ; k ++)
{
int x,y;
x = i + dir[k][0];
y = j + dir[k][1];
if(x < 0 || x >= 3 || y < 0 || y >= 4 || flag[x][y] == 0) continue;
if(abs(mpt[x][y] - mpt[i][j]) == 1) book = false;
}
}
}
if(book) ans ++;
}
void dfs(int index)
{
int x,y;
x = index / 4;
y = index % 4;
if( x == 3)
{
Solve()