第五届蓝桥杯大赛个人赛省赛C/C++A组答案(除编程题)

真题自取:

链接: https://pan.baidu.com/s/1clU-hMI0lV92L2rZYp_5ZQ 
提取码: 8yrd 

1.猜年龄

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

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

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

    答案:10

for i in range(1,100):
    for j in range(i+1,i+8):
        if i*j==(i+j)*6:
            print(i,j)

2.切面条

    一根高筋拉面,中间切一刀,可以得到2根面条。

    如果先对折1次,中间切一刀,可以得到3根面条。

    如果连续对折2次,中间切一刀,可以得到5根面条。

    那么,连续对折10次,中间切一刀,会得到多少面条呢?

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

    答案:1025

def sam(num):
    k=2**num
    k=k*2-(k-1)
    return k

print(sam(10))

3.神奇算式

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

    比如: 

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

    都符合要求。

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

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

    答案:12


def sam(a,b,c):
    kl=(a,b,c)
    a_set=set()
    c_set=set()
    while True:
        if a!=0:
            a_set.add(a%10)
            a=a//10
        else:
            break
    while True:
        if b!=0:
            a_set.add(b%10)
            b=b//10
        else:
            break
    while True:
        if c!=0:
            c_set.add(c%10)
            c=c//10
        else:
            break
    if len(a_set)!=4 or len(c_set)!=4:
        return 0
    if a_set==c_set:
        print(kl)
        return 1
    else:
        return 0


result=0
for i in range(1,1000):
    if i<10:
        for j in range(100,1000):
            if i*j>10000 or i*j<1000:
                continue
            result+=sam(i,j,i*j)
    elif i<100:
        for j in range(10,100):
            if i*j>10000 or i*j<1000:
                continue
            result+=sam(i,j,i*j)
    elif i<1000:
        for j in range(1,10):
            if i*j>10000 or i*j<1000:
                continue
            result+=sam(i,j,i*j)

print(result/2)

4.史丰收速算

史丰收速算法的革命性贡献是:从高位算起,预测进位。不需要九九表,彻底颠覆了传统手算!

    速算的核心基础是:1位数乘以多位数的乘法。

    其中,乘以7是最复杂的,就以它为例。

    因为,1/7 是个循环小数:0.142857...,如果多位数超过 142857...,就要进1

    同理,2/7, 3/7, ... 6/7 也都是类似的循环小数,多位数超过 n/7,就要进n

    下面的程序模拟了史丰收速算法中乘以7的运算过程。

    乘以 7 的个位规律是:偶数乘以2,奇数乘以2再加5,都只取个位。

    乘以 7 的进位规律是:
	满 142857... 进1,
	满 285714... 进2,
	满 428571... 进3,
	满 571428... 进4,
	满 714285... 进5,
	满 857142... 进6

    请分析程序流程,填写划线部分缺少的代码。


//计算个位 
int ge_wei(int a)
{
	if(a % 2 == 0)
		return (a * 2) % 10;
	else
		return (a * 2 + 5) % 10;	
}

//计算进位 
int jin_wei(char* p)
{
	char* level[] = {
		"142857",
		"285714",
		"428571",
		"571428",
		"714285",
		"857142"
	};
	
	char buf[7];
	buf[6] = '\0';
	strncpy(buf,p,6);
	
	int i;
	for(i=5; i>=0; i--){
		int r = strcmp(level[i], buf);
		if(r<0) return i+1;
		while(r==0){
			p += 6;
			strncpy(buf,p,6);
			r = strcmp(level[i], buf);
			if(r<0) return i+1;
			______________________________;  //填空
		}
	}
	
	return 0;
}

//多位数乘以7
void f(char* s) 
{
	int head = jin_wei(s);
	if(head > 0) printf("%d", head);
	
	char* p = s;
	while(*p){
		int a = (*p-'0');
		int x = (ge_wei(a) + jin_wei(p+1)) % 10;
		printf("%d",x);
		p++;
	}
	
	printf("\n");
}

int main()
{
	f("428571428571");
	f("34553834937543");		
	return 0;
}


注意:通过浏览器提交答案。只填写缺少的内容,不要填写任何多余的内容(例如:说明性文字)

    答案:break

5.锦标赛

如果要在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<len) n *= 2;
	
	int* b = (int*)malloc(sizeof(int*) * (2*n-1));
	int i;
	for(i=0; i<n; i++){ 
		if(i<len) 
			b[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);	
}

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

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

    答案:b[k1]>b[k2]

6.扑克序列

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

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

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

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

    答案:2342A3A4

def pan(a):
    for i in range(1,5):
        num=a.index(i)
        if num+i+1<8:
            if a[num+i+1]!=i:
                return
        else:
            return
    print(a)



def sam(a,b,num):
    if num==8:
        pan(a)
        return
    for i in range(4):
        if b[i]!=0:
            b[i]-=1
            a.append(i+1)
            sam(a,b,num+1)
            a.pop()
            b[i]+=1



sam([],[2,2,2,2],0)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值