• 第七届蓝桥杯大赛个人赛省赛(软件类)C语言B组--2016年


    1、

    煤球数目

    有一堆煤球,堆成三角棱锥形。具体:

    第一层放1个,

    第二层3个(排列成三角形),

    第三层6个(排列成三角形),

    第四层10个(排列成三角形),

    ....

    如果一共有100层,共有多少个煤球?

    请填表示煤球总数目的数字。

    思路:1 2 3 4 5 6……这一个等差数列的前n项和为(1+n)*n/2

    第1层的煤球数目为1

    第2层的煤球数目为1+2

    第3层的煤球数目为1+2+3

    ……

    第i层的煤球数组为(1+n)*n/2

    答案:171700

    A[i] = i+a[i-1]  i->1--100

    //煤球数目
    #include<stdio.h>
    #define MAXN 102
    int main(){
    	int i,sum;
    	int a[MAXN] = {0};
    	a[1] = 1;
    	sum = a[1];
    	for(i=2;i<=100;i++){
    		a[i] = a[i-1] + i;
    		sum += a[i];
    	}
    	printf("%d",sum);
    	return 0;
    }  

    2、

    生日蜡烛

    某君从某年开始每年都举办一次生日party,并且每次都要吹熄与年龄相同根数的蜡烛。

    现在算起来,他一共吹熄了236根蜡烛。

    请问,他从多少岁开始过生日party的?

    请填写他开始过生日party的年龄数。

    思路:1 2 3 4 5 6……这一个等差数列的前n项和为(1+n)*n/2

    设从a岁开始过生日,到了b岁一共吹熄了236根蜡烛。

    即为:(a+b)(b-a+1)/2=236

    答案:26

    等差数列

    #include<stdio.h>
    int main(){
    	int x,y;
    	for(x=1;x<=100;x++){
    		for(y=2;y<=100;y++){
    			if((x+y)*(y-x+1) == 2*236)
    				printf("%d",x);
    		}
    	}
    	return 0;
    } 
    

      

    3、

    凑算式

    如图,这个算式中A~I代表1~9的数字,不同的字母代表不同的数字。

    比如:
    6+8/3+952/714 就是一种解法,
    5+3/1+972/486 是另一种解法。
    这个算式一共有多少种解法?

    思路:暴力解决,注意每个字母代表的数字不相等。

    答案:29

    //凑算数
    #include<stdio.h>
    int main(){
    	int a,b,c,d,e,f,g,h,i;
    	int count=0;
    	for(a=1;a<=9;a++){
    		for(b=1;b<=9;b++){
    			if(a==b)
    				continue;
    			for(c=1;c<=9;c++){
    				if(a==c||b==c)
    					continue;
    				for(d=1;d<=9;d++){
    					if(a==d||b==d||c==d)
    						continue;
    					for(e=1;e<=9;e++){
    						if(a==e||b==e||c==e||d==e)
    							continue;
    						for(f=1;f<=9;f++){
    							if(a==f||b==f||c==f||d==f||e==f)
    								continue;
    							for(g=1;g<=9;g++){
    								if(a==g||b==g||c==g||d==g||e==g||f==g)
    									continue;
    								for(h=1;h<=9;h++){
    									if(a==h||b==h||c==h||d==h||e==h||f==h||g==h)
    										continue;
    									for(i=1;i<=9;i++){
    										if(a==i||b==i||c==i||d==i||e==i||f==i||g==i||h==i)
    											continue;
    										if((10-a)*c*(g*100+h*10+i) == b*(g*100+h*10+i) + (d*100+e*10+f)*c)
    											count++;
    											
    //										 if(a+1.0*b/c+(1.0*d*100+e*10*1.0+f*1.0)/(g*100*1.0+h*10*1.0+i*1.0)==10)
    //										 	count++;
    									} 
    								}
    							} 
    						}
    					} 
    				}
    			}
    		}
    	}
    	printf("%d",count);
    }

    4、

    快速排序

    排序在各种场合经常被用到。
    快速排序是十分常用的高效率的算法。
    其思想是:先选一个“标尺”,
    用它把整个队列过一遍筛子,
    以保证:其左边的元素都不大于它,其右边的元素都不小于它。
    这样,排序问题就被分割为两个子区间。
    再分别对子区间排序就可以了。

    //快速排序
    #include <stdio.h>
    void swap(int a[], int i, int j)
    {
    	int t = a[i];
    	a[i] = a[j];
    	a[j] = t;
    }
    
    int partition(int a[], int p, int r)
    {
    	int i = p;
    	int j = r + 1;
    	int x = a[p];
    	while(1){
    		while(i<r && a[++i]<x);
    		while(a[--j]>x);
    		if(i>=j) 
    			break;
    		swap(a,i,j);
    	}
    	swap(a,p,j);//______________________;
    	return j;
    }
    
    void quicksort(int a[], int p, int r)
    {
    	if(p<r){
    		int q = partition(a,p,r);
    		quicksort(a,p,q-1);
    		quicksort(a,q+1,r);
    	}
    }
    
    int main()
    {
    	int i;
    	int a[] = {5,13,6,24,2,8,19,27,6,12,1,17};
    	int N = 12;
    	quicksort(a, 0, N-1);
    	for(i=0; i<N; i++) 
    		printf("%d ", a[i]);
    	printf("
    ");
    	return 0;
    } 

      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 <stdio.h>
    #define N 6
    #define M 5
    #define BUF 1024
    
    void f(int a[], int k, int m, char b[])
    {	//k:
    	int i,j;
    	if(k==N){ 
    		b[M] = 0;
    		if(m==0) 
    			printf("%s
    ",b);
    		return;
    	}
    	for(i=0; i<=a[k]; i++){	//对第k个国家,派出人数 0--a[k] 
    		for(j=0; j<i; j++) 
    			b[M-m+j] = k+'A';
    		f(a,k+1,m-i,b);//______________________;  //填空位置
    	}
    }
    int main()
    {	
    	int  a[N] = {4,2,2,1,1,3};	//a[]:每个国家可以派出的最多的名额 
    	char b[BUF];
    	f(a,0,M,b);
    	return 0;
    } 

    6、

    方格填数

    如图,如下的10个格子,填入0~9的数字。要求:连续的两个数字不能相邻。

    (左右、上下、对角都算相邻)一共有多少种可能的填数方案?

    请填写表示方案数目的整数。

     

    思路:这题方法很简单,暴力求解,依次向每个格子填数与已经填入的进行比较是否连续,即:是否两者之差的绝对值为1。比赛的时候一直在纠结,题干没有说明0~9的数字可以重复使用还是只能用一次,比赛时最后我按照可以重复使用提交的,不知道是不是正确。

    答案:如果数字不可以重复使用,结果为1580

               如果数字可以重复使用,结果为206059714

    //方格填数
    #include<stdio.h>
    #include<math.h> 
    int flag[3][4];
    int mp[3][4];
    int 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;
    	for(i=0;i<10;i++)
    		visit[i] = 0;
    }
    void Solve(){
    	int i,j,k;
    	int direction[8][2] = {
    		{0,1},	//左 
    		{0,-1},	//右 
    		{1,0},
    		{-1,0},
    		{1,1},
    		{1,-1},
    		{-1,1},
    		{-1,-1}
    	};
    	int temp = 1;
    	for(i=0;i<3;i++){
    		for(j=0;j<4;j++){
    			if(flag[i][j] == 0)	
    				continue;
    			for(k=0;k<8;k++){
    				int x,y;
    				x = i + direction[k][0];
    				y = j + direction[k][1];
    				if(x < 0||x >=3 || y<0 || y>=4 || flag[x][y] == 0)	continue;
    				if(abs(mp[x][y] - mp[i][j]) == 1)
    					temp = 0;
    			}
    		}
    	}
    	if(temp ==1)
    	  ans++;
    }
    void dfs(int n){
    	int x,y,i;
    	x = n / 4;	//行 
    	y = n % 4;	//列 
    	if(x == 3){	//递归出口,到dfs(12) 
    		Solve();
    		return;
    	}
    	if(flag[x][y] == 1){	//该处可以赋值0--9 
    		for(i=0;i<10;i++){
    			if(visit[i] == 0){	//
    				visit[i] = 1;
    				mp[x][y] = i;
    				dfs(n+1);
    				visit[i] = 0;
    			}
    		} 
    	}
    	else
    		dfs(n+1); 
    } 
    int main(){
    	init();	//对二维数组进行初始化
    	dfs(0);	
    	printf("%d
    ",ans);	//输出方案数 
    	return 0;
    } 

    7、

    剪邮票

    如【图1.jpg】, 有12张连在一起的12生肖的邮票。

    现在你要从中剪下5张来,要求必须是连着的。

    (仅仅连接一个角不算相连)

    比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。

    请你计算,一共有多少种不同的剪取方法。

     

    思路:先找到5个数的组合,然后从第一个数字开始遍历,经过上下左右操作检测5个数是否都被访问一遍,如果5个数都可以遍历到则种类+1。

    在原图中向上为-4,向下为+4,向左为-1,向右为+1,但是遇到3 4 5 7 8这种4+1=5但是这种情况不符合,所以重构一下原图:

    这样,向上为-5,向下为+5,向左为-1,向右为+1,避免了每行最后一个+1后等于下一行第一个的情况。

    答案:116

    8、

    四平方和

    四平方和定理,又称为拉格朗日定理:

    每个正整数都可以表示为至多4个正整数的平方和。

    如果把0包括进去,就正好可以表示为4个数的平方和。

    比如:

    5 = 0^2 + 0^2 + 1^2 + 2^2

    7 = 1^2 + 1^2 + 1^2 + 2^2

    (^符号表示乘方的意思)

    对于一个给定的正整数,可能存在多种平方和的表示法。

    要求你对4个数排序:

    0 <= a <= b <= c <= d

    并对所有的可能表示法按 a,b,c,d 为联合主键升序排列,最后输出第一个表示法

    程序输入为一个正整数N (N<5000000)

    要求输出4个非负整数,按从小到大排序,中间用空格分开

    例如,输入:

    5

    则程序应该输出:

    0 0 1 2

    再例如,输入:

    12

    则程序应该输出:

    0 2 2 2

    再例如,输入:

    773535

    则程序应该输出:

    1 1 267 838

    资源约定:

    峰值内存消耗 < 256M

    CPU消耗  < 3000ms

    请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

    所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

    注意: main函数需要返回0

    注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。

    注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。

    提交时,注意选择所期望的编译器类型。

    思路:该题为赛前参考题目里的一个代码填空题,暴力解决

    //四平方和
    #include<stdio.h>
    int main(){
    	int a,b,c,d;
    	int N,sum = 0;
    	scanf("%d",&N);
    	for(a=0;a<=2237;a++){
    		if(a*a > N)
    			continue;
    		for(b=a;b<=2237;b++){
    			if(a*a + b*b > N)
    				break;
    			for(c=b;c<=2237;c++){
    				if(a*a + b*b + c*c > N)
    					continue;
    				for(d=c;d<=2237;d++){
    					if(a*a + b*b + c*c +d*d > N)
    						break;
    					sum = a*a+b*b+c*c+d*d;
    					if(sum == N){
    						printf("%d %d %d %d",a,b,c,d);
    						return 0;	//
    					}
    				}
    			}
    		}
    	}
    	return 0;
    }   

    9、

    交换瓶子

    有N个瓶子,编号 1 ~ N,放在架子上。

    比如有5个瓶子:

    2 1 3 5 4

    要求每次拿起2个瓶子,交换它们的位置。

    经过若干次后,使得瓶子的序号为:

    1 2 3 4 5

    对于这么简单的情况,显然,至少需要交换2次就可以复位。

    如果瓶子更多呢?你可以通过编程来解决。

    输入格式为两行:

    第一行: 一个正整数N(N<10000), 表示瓶子的数目

    第二行:N个正整数,用空格分开,表示瓶子目前的排列情况。

    输出数据为一行一个正整数,表示至少交换多少次,才能完成排序。

    例如,输入:

    5

    3 1 2 5 4

    程序应该输出:

    3

    再例如,输入:

    5

    5 4 3 2 1

    程序应该输出:

    2

    资源约定:

    峰值内存消耗 < 256M

    CPU消耗  < 1000ms

    请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

    所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

    注意: main函数需要返回0

    注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。

    注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。

    提交时,注意选择所期望的编译器类型。

    思路:类似选择排序。

    //交换瓶子
    #include<stdio.h>
    #define MAXN 20
    
    int main(){
    	int i,j,n;
    	int count = 0,min_n;
    	int a[MAXN];
    	scanf("%d",&n);
    	
    	for(i=0;i<n;i++){
    		scanf("%d",&a[i]);
    	}
    	for(i=0;i<n;i++){
    		min_n = i;
    		for(j=i+1;j<n;j++){
    			if(a[min_n] > a[j])
    				min_n = j;
    		}
    		if(min_n != i){
    			count++;
    			int t=a[i];
                a[i]=a[min_n];
                a[min_n]=t;
    		}
    	}
    	printf("%d",count);
    	return 0;
    }

    10、

    最大比例

    X星球的某个大奖赛设了M级奖励。每个级别的奖金是一个正整数。

    并且,相邻的两个级别间的比例是个固定值。

    也就是说:所有级别的奖金数构成了一个等比数列。比如:

    16,24,36,54

    其等比值为:3/2

    现在,我们随机调查了一些获奖者的奖金数。

    请你据此推算可能的最大的等比值。

    输入格式:

    第一行为数字N(N<=100),表示接下的一行包含N个正整数

    第二行N个正整数Xi(Xi<1 000 000 000 000),用空格分开。每个整数表示调查到的某人的奖金数额

    要求输出:

    一个形如A/B的分数,要求A、B互质。表示可能的最大比例系数

    测试数据保证了输入格式正确,并且最大比例是存在的。

    例如,输入:

    3

    1250 200 32

    程序应该输出:

    25/4

    再例如,输入:

    4

    3125 32 32 200

    程序应该输出:

    5/2

    再例如,输入:

    3

    549755813888 524288 2

    程序应该输出:

    4/1

    资源约定:

    峰值内存消耗 < 256M

    CPU消耗  < 3000ms

    请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

    所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

    注意: main函数需要返回0

    注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。

    注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。

    提交时,注意选择所期望的编译器类型。

    思路:所有级别的奖金数构成了一个等比数列,公比相同。例如,

    1  2  4  8  16  32这一个等比数列。

    因为题意为随机调查一些获奖者的奖金数,即,抽到的项可能为连续的项也可能是不连续的项。

    如果抽到1  2  4,这三个连续项,公比为4/2=2/1=2。

    如果抽到1  4  8,这三个不连续的项,则相邻项的商为8/4=2, 4/1=4,再从4和2中取最大公约数就为最后的结果。相当于1为数列第一项,4为数列第三项,8为数列第四项,即1=a1  4=a1*r^2   8=a1*r^3,

    8/4=r      4/1=r^2    从r和r^2中得到公比,即为最大的比例。

  • 相关阅读:
    如何查看python的notebook文件.ipynb
    pip3与pyttsx3文字语音转换
    Python字符乱码
    python3的urllib以及urllib2的报错问题
    python人脸对比
    Python 爬取qqmusic音乐url并批量下载
    稳定排序和不稳定排序
    Linux信号、信号处理和信号处理函数
    jQuery ajax表单提交
    Django setting 常用配置
  • 原文地址:https://www.cnblogs.com/Hqx-curiosity/p/11934536.html
Copyright © 2020-2023  润新知