历年蓝桥杯省赛B组真题试题Word文件下载.docx
《历年蓝桥杯省赛B组真题试题Word文件下载.docx》由会员分享,可在线阅读,更多相关《历年蓝桥杯省赛B组真题试题Word文件下载.docx(20页珍藏版)》请在冰豆网上搜索。
生日蜡烛
某君从某年开始每年都举办一次生日party,并且每次都要吹熄与年龄相同根数的蜡烛。
现在算起来,他一共吹熄了236根蜡烛。
请问,他从多少岁开始过生日party的?
请填写他开始过生日party的年龄数。
暴力枚举。
第一重循环枚举刚开始过生日时候的岁数。
第二重循环是枚举现在的岁数
第三重循环就是将刚开始过生日的岁数和现在的岁数加起来。
intstart,end;
for(start=1;
start<
236;
start++)
{
for(end=start;
end<
end++)
{
intsum=0;
for(inti=start;
=end;
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<
<
b<
'
'
a<
num[1]<
num[2]<
num[3]<
endl;
if(num[1]*num[3]*b+num[2]*b+num[3]*a==10*num[3]*b)sum++;
"
*"
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<
sum;
return0;
〔4〕
快速排序
排序在各种场合经常被用到。
快速排序是十分常用的高效率的算法。
其思想是:
先选一个“标尺〞,
用它把整个队列过一遍筛子,
以保证:
其左边的元素都不大于它,其右边的元素都不小于它。
这样,排序问题就被分割为两个子区间。
再分别对子区间排序就可以了。
下面的代码是一种实现,请分析并填写划线局部缺少的代码。
#include<
stdio.h>
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(i<
r&
&
a[++i]<
x);
//由于要按照从小到大排序,就i一直向右移动直到大于x值位置
while(a[--j]>
//一样的,一直左移直到小于x时
if(i>
=j)break;
//如果一直移动到了相交的区间,说明这个区间内都是由小到大的,就直接退拉!
不用交换啦!
swap(a,i,j);
//有的话呢,就交换,这样保证了左小右大。
______________________;
returnj;
voidquicksort(inta[],intp,intr)
if(p<
r)
intq=partition(a,p,r);
quicksort(a,p,q-1);
quicksort(a,q+1,r);
inti;
inta[]={5,13,6,24,2,8,19,27,6,12,1,17};
intN=12;
quicksort(a,0,N-1);
for(i=0;
i<
N;
i++)printf("
%d"
a[i]);
printf("
\n"
);
快速排序。
这里是单步快排。
就是将一堆数按照某个数作为基准数分成左右两堆
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行)
#defineN6
#defineM5
#defineBUF1024
voidf(inta[],intk,intm,charb[])
inti,j;
if(k==N)
b[M]=0;
if(m==0)printf("
%s\n"
b);
return;
=a[k];
i++)
for(j=0;
j<
i;
j++)b[M-m+j]=k+'
A'
;
______________________;
//填空位置
inta[N]={4,2,2,1,1,3};
charb[BUF];
f(a,0,M,b);
仔细阅读代码,填写划线局部缺少的内容。
注意:
不要填写任何已有内容或说明性文字。
这个题目是这样的,对于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
math.h>
int
flag[3][4];
//表示哪些可以填数
mpt[3][4];
//填数
bool
visit[10];
ans
=
0;
void
init()
//初始化
{
i,j;
for(i
0
i
3
++)
for(j
j
4
flag[i][j]
1;
flag[0][0]
flag[2][3]
}
Solve()
dir[8][2]
0,1,0,-1,1,0,-1,0,1,1,1,-1,-1,1,-1,-1};
book
true;
for(int
4;
//判断每个数周围是否满足
if(flag[i][j]
==
0)continue;
for(
k
8
x,y;
x
+
dir[k][0];
y
dir[k][1];
if(x
||
>
flag[x][y]
0)
continue;
if(abs(mpt[x][y]
-
mpt[i][j])
1)
false;
if(book)
++;
dfs(int
index)
index
/
%
if(
3)
Solve()