2014年第五届蓝桥杯C/C++组真题补充训练(一,未完待续,2017.3.6)

1. (C组T1 2')武功秘籍

    小明到X山洞探险,捡到一本有破损的武功秘籍(2000多页!当然是伪造的)。他注意到:书的第10页和第11页在同一张纸上,但第11页和第12页不在同一张纸上。

    小明只想练习该书的第81页到第92页的武功,又不想带着整本书。请问他至少要撕下多少张纸带走?

    这是个整数,请通过浏览器提交该数字,不要填写任何多余的内容。

【分析】与正常书本的标页码方式不同,这本武功秘籍的标页码方式是 1 23 45 67 89 1011 1213……(两数字挨着说明这两个页码在书的同一页),可以笔算模拟求解,也可编程。

源代码:

#include 
int main()
{
	int start,end;                            //起始页码与终止页码 
	int i,count;                              //count记录所需纸张数 
	while(scanf("%d %d",&start,&end)!=EOF)
	{
		count=1;                          //count赋初值1,表示起始页码所在页为第1页
		for(i=start+1;i<=end;i++)         //遇到偶数页码,纸张数+1
		{
			if(i%2==0)
				count++;
		}
		printf("%d\n",count);
	}
	return 0;
}
程序截图:

2014年第五届蓝桥杯C/C++组真题补充训练(一,未完待续,2017.3.6)_第1张图片

【答案】7

2. (C组T2 4')等额本金


    小明从银行贷款3万元。约定分24个月,以等额本金方式还款。


    这种还款方式就是把贷款额度等分到24个月。每个月除了要还固定的本金外,还要还贷款余额在一个月中产生的利息。


    假设月利率是:0.005,即:千分之五。那么,


    第一个月,小明要还本金 1250, 还要还利息:30000 * 0.005,总计 1400.00
    第二个月,本金仍然要还 1250, 但利息为:(30000-1250) * 0.005 总计 1393.75


    请问:小明在第15个月,应该还款多少(本金和利息的总和)?


    请把答案金额四舍五入后,保留两位小数。注意:32.5,一定要写为:32.50


    通过浏览器提交答案,这是一个含有小数点和两位小数的浮点数字。不要写多余内容(例如:多写了“元”或添加说明文字)

【分析】推出公式直接求解

源代码:

#include 
int main()
{
	int i,n;                 //n-第n个月 
	double money=1250,sum;
	while(scanf("%d",&n)!=EOF)
	{
		sum=money+(30000-(n-1)*money)*0.005;
		printf("%.2lf\n",sum);
	}
	return 0;
}
程序截图:

2014年第五届蓝桥杯C/C++组真题补充训练(一,未完待续,2017.3.6)_第2张图片

【答案】1312.50

3. (C组T3 6')猜字母


    把abcd...s共19个字母组成的序列重复拼接106次,得到长度为2014的串。


    接下来删除第1个字母(即开头的字母a),以及第3个,第5个等所有奇数位置的字母。


    得到的新串再进行删除奇数位置字母的动作。如此下去,最后只剩下一个字母,请写出该字母。


    答案是一个小写字母,请通过浏览器提交答案。不要填写任何多余的内容。

【分析】串操作

源代码:

#include 
#include 
#define maxlen 2015
int main()
{
	int i;
	int j=0,k,time=0;           //time记录拼接次数 
	char str[maxlen];
	while(time<106)             //j记录"a~s"串拼接106次后的字符串的长度及其后续变化过程 
	{
		for(i=0;i<19;i++)
			str[j++]='a'+i;
		time++;
	}
	str[j]='\0';
	//printf("%d\n",j);         //(测试用)输出拼接106次后的串 
	//printf("%s\n",str);
	while(j!=1)                 //串长不为1时,取串中所有偶数位置的字母 
	{
		k=0;
		for(i=0;i
程序截图:

2014年第五届蓝桥杯C/C++组真题补充训练(一,未完待续,2017.3.6)_第3张图片

2014年第五届蓝桥杯C/C++组真题补充训练(一,未完待续,2017.3.6)_第4张图片

2014年第五届蓝桥杯C/C++组真题补充训练(一,未完待续,2017.3.6)_第5张图片

【答案】q

另:参考自csdn,补充一种解法:

#include 
using namespace std;

int main(){
	string s="abcdefghijklmnopqrs";
	string ss;
	for(int i=0;i<106;i++){
		ss+=s;		//拼接106次 
	}
	while(ss.size()>1){		//判断循环结束 
		for(int i=0;i
4. (C组T4 4')大衍数列



    中国古代文献中,曾记载过“大衍数列”, 主要用于解释中国传统文化中的太极衍生原理。


    它的前几项是:0、2、4、8、12、18、24、32、40、50 ...


    其规律是:对偶数项,是序号平方再除2,奇数项,是序号平方减1再除2。


    以下的代码打印出了大衍数列的前 100 项。


int main()
{
int i;
for(i=1; i<100; i++){
if(__________________) //填空
printf("%d ", i*i/2);
else
printf("%d ", (i*i-1)/2);
}
printf("\n");
}


    请填写划线部分缺失的代码。通过浏览器提交答案。


注意:不要填写题面已有的内容,也不要填写任何说明、解释文字。

填空后代码:

#include 
int main()
{
	int i;
	for(i=1; i<100; i++)
	{
		if(i%2==0)                     //填空位置 根据序号是奇数还是偶数判断
			printf("%d ", i*i/2);
		else
			printf("%d ", (i*i-1)/2);
	}
	printf("\n");
}
程序截图:

2014年第五届蓝桥杯C/C++组真题补充训练(一,未完待续,2017.3.6)_第6张图片

5. (C组T6 11')神奇算式


    由4个不同的数字,组成的一个乘法算式,它们的乘积仍然由这4个数字组成。


    比如: 


210 x 6 = 1260 
8 x 473 = 3784
27 x 81 = 2187 


    都符合要求。


    如果满足乘法交换律的算式算作同一种情况,那么,包含上边已列出的3种情况,一共有多少种满足要求的算式。


    请填写该数字,通过浏览器提交答案,不要填写多余内容(例如:列出所有算式)。

【分析】4层循环+枚举+暴力求解

源代码:

#include 
int Repeat(int a[],int n)                        //判断等号左侧用"*"隔开的四位数是否有重复
{
	int i,j;
	int flag=1;
	for(i=0;i
程序截图:

2014年第五届蓝桥杯C/C++组真题补充训练(一,未完待续,2017.3.6)_第7张图片

【答案】12

※6. (C组T7 12')绳圈


    今有 100 根绳子,当然会有 200 个绳头。


    如果任意取绳头两两配对,把所有绳头都打结连接起来。最后会形成若干个绳圈(不考虑是否套在一起)。


    我们的问题是:请计算最后将形成多少个绳圈的概率最大?


    注意:结果是一个整数,请通过浏览器提交该数字。不要填写多余的内容。

【分析】动态规划

参考源代码:

#include
#define N 100
using namespace std;

double dp[N+1][N+1] = {0}; 

int main(){
	dp[1][1] = 1;
	for(int i=2;i<=N;i++){
		dp[i][1] = dp[i-1][1] * (2*i-2)/(2*i-1);
		dp[i][i] = dp[i-1][i-1] / (2*i-1);
	}
	
	for(int i=3;i<=N;i++){
		for(int j=2;jmaxR){
			index = i;
			maxR = dp[N][i];
		}	
	}
	cout<

7. (A组T1 2')猜年龄

    小明带两个妹妹参加元宵灯会。别人问她们多大了,她们调皮地说:“我们俩的年龄之积是年龄之和的6倍”。小明又补充说:“她们可不是双胞胎,年龄差肯定也不超过8岁啊。”

    请你写出:小明的较小的妹妹的年龄。

    注意: 只写一个人的年龄数字,请通过浏览器提交答案。不要书写任何多余的内容。

【分析】循环+枚举

源代码:

#include 
int main()
{
	int a,b;               //小/大妹妹年龄
	for(a=1;a<=100;a++)
	{
		for(b=1;b<=100;b++)
		{
			if(a
程序截图:

2014年第五届蓝桥杯C/C++组真题补充训练(一,未完待续,2017.3.6)_第8张图片

【答案】10

※8. (A组T5 11')锦标赛

   如果要在n个数据中挑选出第一大和第二大的数据(要求输出数据所在位置和值),使用什么方法比较的次数最少?我们可以从体育锦标赛中受到启发。


   如图【1.png】所示,8个选手的锦标赛,先两两捉对比拼,淘汰一半。优胜者再两两比拼...直到决出第一名。


   第一名输出后,只要对黄色标示的位置重新比赛即可。


   下面的代码实现了这个算法(假设数据中没有相同值)。


   代码中需要用一个数组来表示图中的树(注意,这是个满二叉树,不足需要补齐)。它不是存储数据本身,而是存储了数据的下标。   
   
   第一个数据输出后,它所在的位置被标识为-1


//重新决出k号位置,v为已输出值 
void pk(int* a, int* b, int n, int k, int v)
{
int k1 = k*2 + 1;
int k2 = k1 + 1;

if(k1>=n || k2>=n){
b[k] = -1;
return;
}

if(b[k1]==v) 
pk(a,b,n,k1,v);
else
pk(a,b,n,k2,v);

//重新比较
if(b[k1]<0){
if(b[k2]>=0)
b[k] = b[k2]; 
else
b[k] = -1;
return;
}

if(b[k2]<0){
if(b[k1]>=0)
b[k] = b[k1]; 
else
b[k] = -1;
return;
}

if(______________________) //填空
b[k] = b[k1];
else
b[k] = b[k2];
}


//对a中数据,输出最大,次大元素位置和值 
void f(int* a, int len)
{
int n = 1;
while(n
int* b = (int*)malloc(sizeof(int*) * (2*n-1));
int i;
for(i=0; iif(ib[n-1+i] = i;
else
b[n-1+i] = -1;
}

//从最后一个向前处理
for(i=2*n-1-1; i>0; i-=2){
if(b[i]<0){
if(b[i-1]>=0)
b[(i-1)/2] = b[i-1]; 
else
b[(i-1)/2] = -1;
}
else{
if(a[b[i]]>a[b[i-1]])
b[(i-1)/2] = b[i];
else
b[(i-1)/2] = b[i-1];
}
}

//输出树根
printf("%d : %d\n", b[0], a[b[0]]);

//值等于根元素的需要重新pk
pk(a,b,2*n-1,0,b[0]);

//再次输出树根
printf("%d : %d\n", b[0], a[b[0]]);

free(b);
}




int main()
{
int a[] = {54,55,18,16,122,17,30,9,58};
f(a,9);
}


    请仔细分析流程,填写缺失的代码。


    通过浏览器提交答案,只填写缺失的代码,不要填写已有代码或其它说明语句等。

图:

2014年第五届蓝桥杯C/C++组真题补充训练(一,未完待续,2017.3.6)_第9张图片

【分析】二叉树的顺序存储结构、递归思想

填空后代码:

#include 
#include 
void pk(int* a, int* b, int n, int k, int v)
{
	int k1 = k*2 + 1;
	int k2 = k1 + 1;
	
	if(k1>=n || k2>=n)
	{
		b[k] = -1;
		return;
	}
	
	if(b[k1]==v) 
		pk(a,b,n,k1,v);
	else
		pk(a,b,n,k2,v);
	
	//重新比较
	if(b[k1]<0)
	{
		if(b[k2]>=0)
			b[k] = b[k2]; 
		else
			b[k] = -1;
		return;
	}
	
	if(b[k2]<0)
	{
		if(b[k1]>=0)
			b[k] = b[k1]; 
		else
			b[k] = -1;
		return;
	}
	
	if(a[b[k1]]>a[b[k2]]) //填空
		b[k] = b[k1];
	else
		b[k] = b[k2];
}

//对a中数据,输出最大,次大元素位置和值 
void f(int* a, int len)
{
	int n = 1;
	while(n0; i-=2)
	{
		if(b[i]<0)
		{
			if(b[i-1]>=0)
				b[(i-1)/2] = b[i-1]; 
			else
				b[(i-1)/2] = -1;
		}
		else
		{
			if(a[b[i]]>a[b[i-1]])
				b[(i-1)/2] = b[i];
			else
				b[(i-1)/2] = b[i-1];
		}
	}
	
	/*for(i=0;i<2*n-1;i++)                     //测试用 
		printf("%d ",b[i]);
	printf("\n");*/
	//输出树根
	printf("%d : %d\n", b[0], a[b[0]]);
	
	//值等于根元素的需要重新pk
	pk(a,b,2*n-1,0,b[0]);
	
	//再次输出树根
	printf("%d : %d\n", b[0], a[b[0]]);
	
	free(b);
}


int main()
{
	int a[] = {54,55,18,16,122,17,30,9,58};
	f(a,9);	
}
程序截图:

2014年第五届蓝桥杯C/C++组真题补充训练(一,未完待续,2017.3.6)_第10张图片

【答案】a[b[k1]]>a[b[k2]

9. (A组T6 12')扑克序列


    A A 2 2 3 3 4 4, 一共4对扑克牌。请你把它们排成一行。
    要求:两个A中间有1张牌,两个2之间有2张牌,两个3之间有3张牌,两个4之间有4张牌。

    请填写出所有符合要求的排列中,字典序最小的那个。

    例如:22AA3344 比 A2A23344 字典序小。当然,它们都不是满足要求的答案。

    请通过浏览器提交答案。“A”一定不要用小写字母a,也不要用“1”代替。字符间一定不要留空格。

【分析】八重循环枚举八张牌,暴力求解。可以发现,符合条件的序列有2个,但是要注意,输出字典序最小的。

源代码:

#include 
#include 
int strnum(char str[],char ch,int len)
{
	int i;
	int count=0;
	for(i=0;i
程序截图:

2014年第五届蓝桥杯C/C++组真题补充训练(一,未完待续,2017.3.6)_第11张图片

【答案】2342A3A4

你可能感兴趣的:(历届蓝桥杯真题——省赛)