2013年第四届蓝桥杯C/C++ C组决赛真题题解

1. 标题:好好学习

    汤姆跟爷爷来中国旅游。一天,他帮助中国的小朋友贴标语。他负责贴的标语是分别写在四块红纸上的四个大字:“好、好、学、习”。但是汤姆不认识汉字,他就想胡乱地贴成一行。

    请你替小汤姆算一下,他这样乱贴,恰好贴对的概率是多少?

    答案是一个分数,请表示为两个整数比值的形式。例如:1/3 或 2/15 等。
如果能够约分,请输出约分后的结果。

    注意:不要书写多余的空格。


    请严格按照格式,通过浏览器提交答案。
    注意:只提交这个比值,不要写其它附加内容,比如:说明性的文字。

【分析】排列组合问题 全排列+枚举

#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
	int a[4]={1,1,2,3};        //1-好 2-学 3-习
	int cnt=0,tot=0;           //cnt-贴对的情况数  tot-可能的情况总数 
	do
	{
		tot++;
		cout<<a[0]<<" "<<a[1]<<" "<<a[2]<<" "<<a[3]<<endl;
		if(a[0]==1 && a[1]==1 && a[2]==2 && a[3]==3)
			cnt++; 
	} while(next_permutation(a,a+4));
	cout<<cnt<<"/"<<tot<<endl;
	return 0;
} 

【答案】1/12

2. 标题:埃及分数

    古埃及曾经创造出灿烂的人类文明,他们的分数表示却很令人不解。古埃及喜欢把一个分数分解为类似: 1/a + 1/b 的格式。

    这里,a 和 b 必须是不同的两个整数,分子必须为 1

    比如,2/15 一共有 4 种不同的分解法(姑且称为埃及分解法):

1/8 + 1/120
1/9 + 1/45
1/10 + 1/30
1/12 + 1/20


    那么, 2/45 一共有多少个不同的埃及分解呢(满足加法交换律的算同种分解)? 请直接提交该整数(千万不要提交详细的分解式!)。

    请严格按照要求,通过浏览器提交答案。
    注意:只提交分解的种类数,不要写其它附加内容,比如:说明性的文字

【分析】循环+枚举

        分析此题,因为要求将分数2/45拆成两项,分子为1,两个分数的分母为a和b,因此可采用枚举法,枚举所有可能情况(这里取a<b)。在此基础上,需要注意当a>=45时是无解的,因为要求a和b必须是不同的两个整数。

#include <stdio.h>
#include <math.h>
int main()
{
	int cnt=0;
	int a,b;
	double left,right;
	for(a=2;a<45;a++)
	{
		for(b=a+1;b<=10000000;b++)
		{
			left=1.0/a+1.0/b;
			right=2.0/45;
			if(fabs(left-right)<1e-8)
			{
				printf("1/%d+1/%d=2/45\n",a,b);
				cnt++;
			}
		}
	}
	printf("%d\n",cnt);
	return 0;
}

【答案】7

3. 标题:正负金字塔

    看下面的图形:

     + - + - - + - + - - + - - + -
      - - - + - - - - + - - + - -
       + + - - + + + - - + - - +
        + - + - + + - + - - + -
         - - - - + - - - + - -
          + + + - - + + - - +
           + + - + - + - + -
            + - - - - - - -
             - + + + + + +
              - + + + + +
               - + + + +
                - + + +
                 - + +
                  - +
                   -

    它是由正号和负号组成的金字塔形状。其规律是:每个符号的左上方和右上方符号如果相同,则输出为正号,否则为负号。其第一行数据由外部输入。

    以下代码实现了该功能。请仔细阅读代码,并填写划线部分缺失的代码。

【分析】字符处理问题

        要注意填空位置等号左边的x[i]是当前行的字符,等号右边的x[i]和x[i+1]是上一行的字符,即当前位置字符的左上方和右上方字符。(PS:题目有一个特别特别特别坑的地方,测试函数中的test应改为main,否则无法编译。。)

#include <stdio.h>
void f(char* x, int space, int n)
{
	int i;
	if(n<1)                           //所打印行的字符数为0,直接返回,结束 
		return;

	for(i=0; i<space; i++)            //打印第一个字符前面的空格 
		printf(" ");
	for(i=0; i<n; i++)                //打印当前行的上一行的n个字符 
		printf("%c ", x[i]);
	printf("\n");
	
	for(i=0; i<n-1; i++)              //确定当前行的字符,括号中的x[i]和x[i+1]是当前符号左上方和右上方的符号 
		x[i] =(x[i]==x[i+1])?'+':'-';
	f(x,space+1,n-1);
}

// 用于f的测试
int main()
{
	char x[] = "+-+--+-+--+--+-";     //第一行数据由外部输入 
	//char x[] = "+-+";
	f(x, 5, sizeof(x)-1);
	return 0;
}
【答案】(x[i]==x[i+1])?'+':'-'



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值