蓝桥杯软件大赛c真题及参考答案文档格式.docx
《蓝桥杯软件大赛c真题及参考答案文档格式.docx》由会员分享,可在线阅读,更多相关《蓝桥杯软件大赛c真题及参考答案文档格式.docx(79页珍藏版)》请在冰点文库上搜索。
nday(yb,
mb,
db);
yp,
np;
//print
for(int
i
yb;
>
0;
i++)
yp
i;
np
n;
if(isLeap(i))
-=
366;
else
365;
}
printf("
%d-"
yp);
ymd(np);
return
d)
a[2][12]
{{31,
28,
31,
30,
31},
{31,
29,
31}};
(m
1);
+=
a[isLeap(y)][i];
d;
n)
mp,
dp;
dp
mp
a[isLeap(i)][i];
%d-%d\n"
1,
dp);
y)
if((y
%
4
==
0
&
y
100
!
0)
||
(y
400
0))
1;
最后答案
1799-07-16
2.标题:
马虎的算式
小明是个急性子,上小学的时候经常把老师写在黑板上的题目抄错了。
有一次,老师出的题目是:
36x495=?
他却给抄成了:
396x45=?
但结果却很戏剧性,他的答案竟然是对的!
!
因为36*495=396*45=17820
类似这样的巧合情况可能还有很多,比如:
27*594=297*54
假设abcde代表1~9不同的5个数字(注意是各不相同的数字,且不含0)
能满足形如:
ab*cde=adb*ce这样的算式一共有多少种呢?
请你利用计算机的优势寻找所有的可能,并回答不同算式的种类数。
满足乘法交换律的算式计为不同的种类,所以答案肯定是个偶数。
答案直接通过浏览器提交。
只提交一个表示最终统计种类数的数字,不要提交解答过程或其它多余的内容。
参考答案:
穷举法
#include<
intmain()
{
inta,b,c,d,e,n=0;
for(a=1;
a<
=9;
a++)
for(b=1;
b<
b++)
for(c=1;
c<
c++)
for(d=1;
d<
d++)
for(e=1;
e<
e++)
if(a!
=b&
a!
=c&
=d&
=e&
b!
c!
d!
=e)
if((a*10+b)*(c*100+d*10+e)==(a*100+d*10+b)*(c*10+e))
{
printf("
%ld\n"
(a*10+b)*(c*100+d*10+e));
n++;
}
printf("
n=%d"
n);
return0;
}
运行结果:
3.题目标题:
第39级台阶
小明刚刚看完电影《第39级台阶》,离开电影院的时候,他数了数礼堂前的台阶数,恰好是39级!
站在台阶前,他突然又想着一个问题:
如果我每一步只能迈上1个或2个台阶。
先迈左脚,然后左右交替,最后一步是迈右脚,也就是说一共要走偶数步。
那么,上完39级台阶,有多少种不同的上法呢?
请你利用计算机的优势,帮助小明寻找答案。
要求提交的是一个整数。
不要提交解答过程,或其它的辅助说明文字。
分析
该情景可简化为39与0和1的关系问题,还有一个限制条件,一共要走偶数步。
这道题可以有两种思路,递归与排列组合,代码都不长,重在思考过程。
fun(int
r,
s)
if(r
s
2
n++;
2;
fun(r
i,
fun(39,
0);
%d\n"
完全转化为数学问题,实际上就是:
n=c(38,1)+(36,3)+...+c(20,19)
51167078
4.标题:
黄金连分数
黄金分割数0.61803...是个无理数,这个常数十分重要,在许多工程问题中会出现。
有时需要把这个数字求得很精确。
对于某些精密工程,常数的精度很重要。
也许你听说过哈勃太空望远镜,它首次升空后就发现了一处人工加工错误,对那样一个庞然大物,其实只是镜面加工时有比头发丝还细许多倍的一处错误而已,却使它成了“近视眼”!
言归正传,我们如何求得黄金分割数的尽可能精确的值呢?
有许多方法。
比较简单的一种是用连分数:
1
黄金数=---------------------
1+-----------------
1+-------------
1+---------
1+...
这个连分数计算的“层数”越多,它的值越接近黄金分割数。
请你利用这一特性,求出黄金分割数的足够精确值,要求四舍五入到小数点后100位。
小数点后3位的值为:
0.618
小数点后4位的值为:
0.6180
小数点后5位的值为:
0.61803
小数点后7位的值为:
0.6180340
(注意尾部的0,不能忽略)
你的任务是:
写出精确到小数点后100位精度的黄金分割值。
尾数的四舍五入!
尾数是0也要保留!
显然答案是一个小数,其小数点后有100位数字,请通过浏览器直接提交该数字。
不要提交解答过程,或其它辅助说明类的内容。
按照题目给出的一种简单方法,可以用斐波纳契数列和模拟手算除法实现。
黄金分割数实际上是相邻的两个斐波那契数的商。
对于模拟手算除法,用下面代码所示的for循环即可实现。
但是这种方法的精确度可能不够。
define
F
50
unsigned
long
fib[1000];
f
a[101];
fib[0]
fib[1]
fib[i]
1e18;
fib[i
1]
2];
f++;
f);
x
fib[F
1];
101;
a[i]
/
y;
(x
*
10;
%d"
a[i]);
0.6180339887498948481971959525508621220510663574518538453723187601229582821971784348083863296133320592
5.题目标题:
前缀判断
如下的代码判断needle_start指向的串是否为haystack_start指向的串的前缀,如不是,则返回NULL。
比如:
"
abcd1234"
就包含了"
abc"
为前缀
char*prefix(char*haystack_start,char*needle_start)
char*haystack=haystack_start;
char*needle=needle_start;
while(*haystack&
*needle){
if(______________________________)returnNULL;
//填空位置
}
//参考答案*(haystack++)
*(needle++)
if(*needle)returnNULL;
returnhaystack_start;
请分析代码逻辑,并推测划线处的代码,通过网页提交。
仅把缺少的代码作为答案,千万不要填写多余的代码、符号或说明文字!
6.标题:
三部排序
一般的排序有许多经典算法,如快速排序、希尔排序等。
但实际应用时,经常会或多或少有一些特殊的要求。
我们没必要套用那些经典算法,可以根据实际情况建立更好的解法。
比如,对一个整型数组中的数字进行分类排序:
使得负数都靠左端,正数都靠右端,0在中部。
注意问题的特点是:
负数区域和正数区域内并不要求有序。
可以利用这个特点通过1次线性扫描就结束战斗!
以下的程序实现了该目标。
其中x指向待排序的整型数组,len是数组的长度。
voidsort3p(int*x,intlen)
intp=0;
intleft=0;
intright=len-1;
while(p<
=right){
if(x[p]<
0){
intt=x[left];
x[left]=x[p];
x[p]=t;
left++;
p++;
}
elseif(x[p]>
intt=x[right];
x[right]=x[p];
right--;
else{
__________________________;
//填空位置p++;
如果给定数组:
25,18,-2,0,16,-5,33,21,0,19,-16,25,-3,0
则排序后为:
-3,-2,-16,-5,0,0,0,21,19,33,25,16,18,25
请分析代码逻辑,并推测划线处的代码,通过网页提交
该三部排序算法的直观意思就是,负数放左边,正数放右边,零放在中间。
那样,每个数就要判断一下,放在哪里,该如何移动。
一边测试,一边找方法,速度还是挺快的。
7.标题:
错误票据
某涉密单位下发了某种票据,并要在年终全部收回。
每张票据有唯一的ID号。
全年所有票据的ID号是连续的,但ID的开始数码是随机选定的。
因为工作人员疏忽,在录入ID号的时候发生了一处错误,造成了某个ID断号,另外一个ID重号。
你的任务是通过编程,找出断号的ID和重号的ID。
假设断号不可能发生在最大和最小号。
要求程序首先输入一个整数N(N<
100)表示后面数据行数。
接着读入N行数据。
每行数据长度不等,是用空格分开的若干个(不大于100个)正整数(不大于100000)
每个整数代表一个ID号。
要求程序输出1行,含两个整数mn,用空格分隔。
其中,m表示断号ID,n表示重号ID
例如:
用户输入:
2
568119
10129
则程序输出:
79
再例如:
6
164178108109180155141159104182179118137184115124125129168196
172189127107112192103131133169158
128102110148139157140195197
185152135106123173122136174191145116151143175120161134162190
149138142146199126165156153193144166170121171132101194187188
113130176154177120117150114183186181100163160167147198111119
105120
资源约定:
峰值内存消耗<
64M
CPU消耗<
1000ms
请严格按要求输出,不要画蛇添足地打印类似:
“请您输入...”的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:
main函数需要返回0
只使用ANSIC/ANSIC++标准,不要调用依赖于编译环境或操作系统的特殊函数。
所有依赖的函数必须明确地在源文件中#include<
xxx>
,不能通过工程设置而省略常用头文件。
提交时,注意选择所期望的编译器类型。
intmain()
{
inta[10001]={0};
longm,min=100000,max=0,i,n;
charc;
scanf("
&
for(i=0;
i<
i++)
while
(1)
{
scanf("
%ld"
m);
if(m>
max)max=m;
if(m<
min)min=m;
a[m]++;
c=getchar();
if(c!
='
'
)break;
}
for(i=min;
=max;
{
if(a[i]==0)printf("
%ld"
i);
if(a[i]==2)m=i;
printf("
m);
return0;
}
8.题目标题:
翻硬币
小明正在玩一个“翻硬币”的游戏。
桌上放着排成一排的若干硬币。
我们用*表示正面,用o表示反面(是小写字母,不是零)。
比如,可能情形是:
**oo***oooo
如果同时翻转左边的两个硬币,则变为:
oooo***oooo
现在小明的问题是:
如果已知了初始状态和要达到的目标状态,每次只能同时翻转相邻的两个硬币,那么对特定的局面,最少要翻动多少次呢?
我们约定:
把翻动相邻的两个硬币叫做一步操作,那么要求:
程序输入:
两行等长的字符串,分别表示初始状态和要达到的目标状态。
每行的长度<
1000
程序输出:
一个整数,表示最小操作步数
**********
o****o****
程序应该输出:
5
*o**o***o***
*o***o**o***
1
参考答案
#include<
string.h>
#defineMAX1000+10
intminu[MAX],sub[MAX],sq[MAX];
intx;
voidsqrt_int(char*,int);
charn[MAX],m[MAX];
scanf("
%s"
n);
scanf("
m);
inta[MAX],b[MAX],s[MAX],S[MAX];
intc,i,j,k,na,nb;
intlen_n,len_m;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(s,0,sizeof(s));
memset(S,0,sizeof(S));
len_n=strlen(n),len_m=strlen(m);
sqrt_int(n,len_n);
for(na=x,i=0;
x>
=0;
i++)a[i]=sq[x--];
sqrt_int(m,len_m);
for(nb=x,i=0;
i++)b[i]=sq[x--];
for(i=0;
i<
=na;
i++)
for(k=i,c=j=0;
j<
=nb+1;
j++,k++)
{
s[k]=(a[i]*b[j])%10+c;
c=(a[i]*b[j])/10;
if(s[k]>
=10){s[k]-=10;
c++;
}
S[k]+=s[k];
if(S[k]>
=10){S[k]-=10;
S[k+1]++;
for(i=MAX-1;
i>
i--)if(S[i])break;
for(j=i;
j>
j--)printf("
S[j]);
putchar('
\n'
);
voidsqrt_int(char*minu_char,intlen)
inti,j,k,m;
ints,c,flag;
intfirst,num;
memset(minu,0,sizeof(minu));
memset(sub,0,sizeof(sub));
memset(sq,0,sizeof(sq));
if(len%2)
minu[0]=minu_char[0]-'
0'
;
for(num=3;
num>
num--)if(minu[0]>
=num*num)break;
sq[x=0]=num;
minu[0]-=num*num;
first=1;
else
sq[x=0]=0;
first=0;
for(i=first;
len;
i+=2)
minu[i]=minu_char[i]-'
minu[i+1]=minu_char[i+1]-'
memset(sub,0,sizeof(sub));
for(k=9;
k>
k--)
sub[i+1]=k;
c=0;
for(m=i,j=x;
j--,m--)
s=sq[j]*2;
sub[m]=s%10+c;
c=s/10;
sub[m]=c;
for(m=i+1;
m>
m--)
s=sub[m]*k;