2019第十届蓝桥杯C/C++省赛B组部分试题解析(C语言实现)
1.C
分析:
该题为三阶斐波那契数列的求解问题,由于数据较大,受数据类型内存空间影响,int,long,long long等数据内存空间不足,不能直接计算。在这里,只需要取后四位,可以参考取模运算(%10000)获得后四位数值。
代码如下:
#include<stdio.h>
int a[20190324];//数组空间太大,放在main函数外面
int main()
{
a[0]=a[1]=a[2]=1;
for(int i=3;i<20190324;i++)
{
a[i]=(a[i-3]+a[i-2]+a[i-1])%10000;
}
printf("%d",a[20190323]);
}
2.D
分析:
三个不同的数,可以考虑升序排列,不可包含2,4。
代码如下:
#include<stdio.h>
int f(int m)//定义函数判断是否含2,4
{
int n;
while(m)
{
n=m%10;
m/=10;
if(n==2||n==4)
return 0;//含2,4返回0,结束计算
}
return 1;
}
int main()
{
int s=0;//s相当于一个计数器,每找到一个组合加一
for(int a=1;a<2019;a++)
{
if(f(a))//当a符合条件时执行循环,减少循环次数,提高计算效率
{
for(int b=a+1;b<2019;b++)
{
if(f(b))
{
int c=2019-a-b;
if(f(c)&&c>b)s++;
}
}
}
}
printf("%d",s);
}
3.F
分析:
处理含有特定数字的元素可采用上文D的处理方法。
代码如下:
#include<stdio.h>
int f(int m)
{
int n;
while(m)
{
n=m%10;
m/=10;
if(n==2||n==0||n==1||n==9)
return 1;
}
}
int main()
{
int x,sum=0;
scanf("%d",&x);
for(int i=1;i<=x;i++)
{
if(f(i))sum+=i;
}
printf("%d",sum);
}
4.G
分析:
注意二叉树的深度从上往下递减,最上处为根部,深度是1;二叉树最底层不一定排满。若使用数组,除最上层下标为0,之后每一层下标j满足2flour+1<=j<(2flour+1)+1。(flour=deep-2)
代码如下:
#include<stdio.h>
int a[10000];
int main()
{
int n,i,j,sum=0/*初始化相同深度的权值之和*/,deep=1/*根的深度*/,f=1/*定义最大深度*/,max;//最大的权值之和
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
max=a[0];
for(i=1;i<n;i=2*i+1)//从第二层开始算
{
deep++;
for(j=i;j<2*i+1;j++)
{
sum+=a[j];
}
if(max<sum)
{
max=sum;
f=deep;
}
sum=0;//初始权值之和,便于下次运算
}
printf("%d",f);
return 0;
}
5.H
分析:
大多数同学一开始可能都会出现和笔者一眼的错误:先排序,算出相邻两项差的最小值,作为公差,实际上应该取相邻两项差的最大公因数作为公差。其次,排序方法会影响计算速度,这里运用快速排序方法(quick sort),包含分治法和递归的运用。冒泡排序法对于数据数量过多时的问题处理效率不高。
代码如下:
#include<stdio.h>
int a[100000];
void quicksort(int a[],int left, int right);
int gcd(int m, int n);
int main()
{
int N,i=0,k,n,max;
scanf("%d", &N);
while(i<N)
{
scanf("%d", &a[i]);
i++;
}
quicksort(a,0,N-1);
max=a[1]-a[0];
if(a[1]==a[0])//注意先判断前两项是否相等,差不相同才能进行最大公因数的计算
{
n=N;
}
else
{
for(k=1;k<N-1;k++)
{
max=gcd(max,(a[k+1]-a[k]));
}
n=(a[N-1]-a[0])/max+1;}
printf("%d",n);
return 0;
}
void quicksort(int a[], int left, int right)
{
int mid, i=left, j=right,temp;
mid=a[(left+right)/2];
while(i<=j)
{
while(a[i]<mid)
{
i++;
}
while(a[j]>mid)
{
j--;
}
if(i<=j)
{
temp=a[i];
a[i]=a[j];
a[j]=temp;
i++;
j--;
}
}
if(left<j)
{
quicksort(a,left,j);
}
if(i<right)
{
quicksort(a,i,right);
}
}
int gcd(int m, int n)
{
if(n%m==0)
return m;
else
return gcd(n%m,m);
}
本代码由我和一位同学一起完成,她提供整体框架,我帮她优化。
其他的等做完在补充。