第三届全国软件大赛决赛C本科真题与答案详析.docx
《第三届全国软件大赛决赛C本科真题与答案详析.docx》由会员分享,可在线阅读,更多相关《第三届全国软件大赛决赛C本科真题与答案详析.docx(24页珍藏版)》请在冰豆网上搜索。
第三届全国软件大赛决赛C本科真题与答案详析
第三届“蓝桥杯”全国软件专业人才设计与创业大赛全国总决赛
C/C++程序设计本科组比赛
选手须知:
●比赛时间为4小时(9:
00-13:
00)。
●参赛选手切勿在提交的代码中书写“姓名”、“考号”,“院校名”等身份信息或其它与竞赛题目无关的内容,否则成绩无效。
●试题包含三种类型:
“结果填空”、“代码填空”与“程序设计”,总计100分。
结果填空:
5分
代码填空:
16分
程序设计:
19+27+33=79分
结果填空题:
要求参赛选手根据题目描述直接填写结果。
求解方式不限。
不要求源代码。
把结果填空的答案存入【准考证+姓名文件夹】下对应题号的“解答.txt”中即可。
代码填空题:
要求参赛选手在弄清给定代码工作原理的基础上填写缺失的部分,使得程序逻辑正确、完整。
所填写的代码不超过一条语句(即中间不能出现分号)。
把代码填空的答案(仅填空处的答案,不包括题面已存在的代码)存入【准考证+姓名文件夹】下对应题号的“解答.txt”中即可。
程序设计题目:
要求选手设计的程序对于给定的输入能给出正确的输出结果。
选手的程序只有能运行出正确结果的时候才有机会得分。
注意:
在评卷时使用的输入数据与试卷中给出的实例数据可能是不同的。
选手的程序必须是通用的,不能只对试卷中给定的数据有效。
对每个编程题目,要求选手把所有函数写在一个文件中。
调试好后,存入与【准考证+姓名文件夹】下对应题号的“解答.txt”中即可。
相关的工程文件不要拷入。
对于编程题目,要求选手给出的解答完全符合ANSIC++标准,不能使用诸如绘图、Win32API、中断调用、硬件操作或与操作系统相关的API。
代码中允许使用STL类库,但不能使用MFC或ATL等非ANSIc++标准的类库。
例如,不能使用CString类型(属于MFC类库)。
1.结果填空(满分5分)
题目在【准考证+姓名文件夹】下对应题号的“题目.rar”中,请先解压该文件。
解压密码以考场公布为准。
把答案存入【准考证+姓名文件夹】下对应题号的“解答.txt”中即可。
直接写在题面中不能得分。
如果有多个答案,每个答案占一行。
2.代码填空(满分16分)
题目在【准考证+姓名文件夹】下对应题号的“题目.rar”中,请先解压该文件。
解压密码以赛场公布为准。
仔细阅读和调试题目提供的源代码,根据要求填写缺失的代码部分。
注意:
请把填空的答案(仅填空处的答案,不包括题面)存入【准考证+姓名文件夹】下对应题号的“解答.txt”中即可。
直接写在题面中不能得分。
填空内容不能超过一条语句(即中间不会含有分号)。
3.程序设计(满分19分)
题目在【准考证+姓名文件夹】下对应题号的“题目.rar”中,请先解压该文件。
解压密码以赛场公布为准。
仔细阅读题目要求,根据题意编写调试代码。
请把所有函数写在同一个文件中,调试好后,存入与【准考证+姓名文件夹】下对应题号的“解答.txt”中即可。
相关的工程文件不要拷入。
4.程序设计(满分27分)
题目在【准考证+姓名文件夹】下对应题号的“题目.rar”中,请先解压该文件。
解压密码以赛场公布为准。
仔细阅读题目要求,根据题意编写调试代码。
请把所有函数写在同一个文件中,调试好后,存入与【准考证+姓名文件夹】下对应题号的“解答.txt”中即可。
相关的工程文件不要拷入。
5.程序设计(满分33分)
题目在【准考证+姓名文件夹】下对应题号的“题目.rar”中,请先解压该文件。
解压密码以赛场公布为准。
仔细阅读题目要求,根据题意编写调试代码。
请把所有函数写在同一个文件中,调试好后,存入与【准考证+姓名文件夹】下对应题号的“解答.txt”中即可。
相关的工程文件不要拷入。
1.星期几。
1949年的国庆节(10月1日)是星期六。
今年(2012)的国庆节是星期一。
那么,从建国到现在,有几次国庆节正好是星期日呢?
只要答案,不限手段!
可以用windows日历,windows计算器,Excel公式,。
。
。
。
。
当然,也可以编程!
不要求写出具体是哪些年,只要一个数目!
千万不要提交源代码!
答案不要写在这里,写在“解答.txt”中
答案:
9
参考代码:
#include7
voidmain(){
intk,i,j;
j=6;//星期六
k=0;
for(i=1950;i<=2012;i++){
if(i%4!
=0||(i%100==0&&i%400!
=0))
j+=1;
else
j+=2;
if(j%7==0)
k++;
}
printf("%d\n",k);
}
2.数据压缩
【代码填空】(满分16分)
某工业监控设备不断发回采样数据。
每个数据是一个整数(0到1000之间)。
各个数据间用空白字符(空格,TAB或回车换行)分隔。
这些数据以文本形式被存储在文件中。
因为大多数时候,相邻的采样间隔数据是相同的,可以利用这个特征做数据的压缩存储。
其方法是:
对n(n>1)个连续相同的数字只记录n和该数字本身;对m(m>0)个连续不重复的数字,则记录m*-1和这些数字本身(之所以用负数,是为了与第一种情况区分,便于解压缩)。
例如:
采样数字:
12343425252525111517281422222213
则根据上述规则变化后:
-112234425-51115172814322-113
下面的程序实现了这个功能。
请仔细阅读分析代码,填写空白的部分。
voidpop(ints,int*buf,intc,FILE*fp)
{
inti;
if(s)
{
fprintf(fp,"%d%d",c,*buf);
}
else
{
fprintf(fp,"%d",-c);
for(i=0;i{
fprintf(fp,"%d",buf[i]);
}
}
}
voiddopack(FILE*r,FILE*w)
{
intbuf[BUF_N];
intpos=0;//下一个数字在buf中将要存放的位置
intc=0;//当前段已读入的整数个数
intpst;
intcst;
while(fscanf(r,"%d",buf+pos)==1)
{
if(c==0)
{
c=pos=1;
continue;
}
if(c==1)
{
pst=buf[0]==buf[1];
pos=pos+1-pst;
c=2;
continue;
}
cst=buf[pos-1]==buf[pos];
if(pst&&!
cst)
{
pop(pst,buf,c,w);
buf[0]=buf[1];
c=pos=1;
pst=cst;
}
elseif(!
pst&&cst||pos==BUF_N-1)
{
pop(pst,buf,c-1,w);
buf[0]=buf[pos-1];
c=2;
if(!
cst)
{
buf[1]=buf[pos];
pos=2;
}
else
{
pos=1;
pst=______________;//填空1
}
}
else
{
c++;
if(!
pst)pos++;
}
}//while
if(c>0)_____________________________;//填空2
}
voidmain()
{
FILE*rfp;
FILE*wfp;
if((rfp=fopen(RFILE,"r"))==NULL)
{
printf("cannotopen%s!
\n",RFILE);
exit
(1);
}
if((wfp=fopen(WFILE,"w"))==NULL)
{
printf("cannotopen%s!
\n",WFILE);
fclose(rfp);
exit
(2);
}
dopack(rfp,wfp);
fclose(wfp);
fclose(rfp);
}
【注意】
只填写缺少的部分,不要抄写已有的代码。
所填写代码不超过1条语句(句中不会含有分号)
所填代码长度不超过256个字符。
答案写在“解答.txt”中,不要写在这里!
答案:
1
pop(pst,buf,c,w)
3.拼音字母
【编程题】(满分19分)
在很多软件中,输入拼音的首写字母就可以快速定位到某个词条。
比如,在铁路售票软件中,输入:
“bj”就可以定位到“北京”。
怎样在自己的软件中实现这个功能呢?
问题的关键在于:
对每个汉字必须能计算出它的拼音首字母。
GB2312汉字编码方式中,一级汉字的3755个是按照拼音顺序排列的。
我们可以利用这个特征,对常用汉字求拼音首字母。
GB2312编码方案对每个汉字采用两个字节表示。
第一个字节为区号,第二个字节为区中的偏移号。
为了能与已有的ASCII编码兼容(中西文混排),区号和偏移编号都从0xA1开始。
我们只要找到拼音a,b,c,...x,y,z每个字母所对应的GB2312编码的第一个汉字,就可以定位所有一级汉字的拼音首字母了(不考虑多音字的情况)。
下面这个表给出了前述信息。
请你利用该表编写程序,求出常用汉字的拼音首字母。
a啊B0A1
b芭B0C5
c擦B2C1
d搭B4EE
e蛾B6EA
f发B7A2
g噶B8C1
h哈B9FE
j击BBF7
k喀BFA6
l垃C0AC
m妈C2E8
n拿C4C3
o哦C5B6
p啪C5BE
q期C6DA
r然C8BB
s撒C8F6
t塌CBFA
w挖CDDA
x昔CEF4
y压D1B9
z匝D4D1
【输入、输出格式要求】
用户先输入一个整数n(n<100),表示接下来将有n行文本。
接着输入n行中文串(每个串不超过50个汉字)。
程序则输出n行,每行内容为用户输入的对应行的汉字的拼音首字母。
字母间不留空格,全部使用大写字母。
例如:
用户输入:
3
大家爱科学
北京天安门广场
软件大赛
则程序输出:
DJAKX
BJTAMGC
RJDS
【注意】
请仔细调试!
您的程序只有能运行出正确结果的时候才有机会得分!
在评卷时使用的输入数据与试卷中给出的实例数据可能是不同的。
请把所有函数写在同一个文件中,调试好后,拷贝到【考生文件夹】下对应题号的“解答.txt”中即可。
相关的工程文件不要拷入。
源代码中不能使用诸如绘图、Win32API、中断调用、硬件操作或与操作系统相关的API。
允许使用STL类库,但不能使用MFC或ATL等非ANSIc++标准的类库。
例如,不能使用CString类型(属于MFC类库),不能使用randomize,random函数(不属于ANSIC++标准)
参考代码:
#include
voidmain(){
inta[26]={0XB0C5,0XB2C1,0XB4EE,0XB6EA,0XB7A2,0XB8C1,
0XB9FE,0XBBF7,0XBBF7,0XBFA6,0XC0AC,0XC2E8,0XC4C3,
0XC5B6,0XC5BE,0XC6DA,0XC8BB,0XC8F6,0XCBFA,
0XCDDA,0XCDDA,0XCDDA,0XCEF4,0XD1B9,0XD4D1,
0XFFFF+1
};
inti,j,k,t,n;
chars[101]={"北京天安门广场"};
charout[5100]={""};
t=0;
scanf("%d",&n);
while(n){
scanf("%s",s);
j=0;
while(s[j]!
='\0'){
k=(unsignedchar)(s[j])*256+(unsignedchar)(s[j+1]);
for(i=0;k>=a[i];i++);
out[t++]='A'+i;
j+=2;
}
out[t++]='\n';
n--;
}
printf("%s",out);
}
4.DNA比对
【编程题】(满分27分)
脱氧核糖核酸即常说的DNA,是一类带有遗传信息的生物大分子。
它由4种主要的脱氧核苷酸(dAMP、dGMP、dCMT和dTMP)通过磷酸二酯键连接而成。
这4种核苷酸可以分别记为:
A、G、C、T。
DNA携带的遗传信息可以用形如:
AGGTCGACTCCA....的串来表示。
DNA在转录复制的过程中可能会发生随机的偏差,这才最终造就了生物的多样性。
为了简化问题,我们假设,DNA在复制的时候可能出现的偏差是(理论上,对每个碱基被复制时,都可能出现偏差):
1.漏掉某个脱氧核苷酸。
例如把AGGT复制成为:
AGT
2.错码,例如把AGGT复制成了:
AGCT
3.重码,例如把AGGT复制成了:
AAGGT
如果某DNA串a,最少要经过n次出错,才能变为DNA串b,则称这两个DNA串的距离为n。
例如:
AGGTCATATTCC与CGGTCATATTC的距离为2
你的任务是:
编写程序,找到两个DNA串的距离。
【输入、输出格式要求】
用户先输入整数n(n<100),表示接下来有2n行数据。
接下来输入的2n行每2行表示一组要比对的DNA。
(每行数据长度<10000)
程序则输出n行,表示这n组DNA的距离。
例如:
用户输入:
3
AGCTAAGGCCTT
AGCTAAGGCCT
AGCTAAGGCCTT
AGGCTAAGGCCTT
AGCTAAGGCCTT
AGCTTAAGGCTT
则程序应输出:
1
1
2
【注意】
请仔细调试!
您的程序只有能运行出正确结果的时候才有机会得分!
在评卷时使用的输入数据与试卷中给出的实例数据可能是不同的。
请把所有函数写在同一个文件中,调试好后,拷贝到【考生文件夹】下对应题号的“解答.txt”中即可。
相关的工程文件不要拷入。
源代码中不能使用诸如绘图、Win32API、中断调用、硬件操作或与操作系统相关的API。
允许使用STL类库,但不能使用MFC或ATL等非ANSIc++标准的类库。
例如,不能使用CString类型(属于MFC类库),不能使用randomize,random函数(不属于ANSIC++标准)
参考代码:
#include
#include
intmain(){
chara[10000]={""},b[10000]={""};
inti,j,k,lena,lenb;
intlu,ru;
while(scanf("%s%*c%s",a,b)!
=EOF){
intc[10001]={0};
for(i=1;a[i-1]!
='\0';i++){
lu=c[0];
c[0]=i;//i,0
for(j=1;b[j-1]!
='\0';j++){
ru=c[j];
c[j]++;//漏掉i,即修正一次,c[i-1][j]+1
if(a[i-1]==b[j-1]&&(c[j-1]+1)c[j]=c[j-1]+1;
}
k=lu+(a[i-1]!
=b[j-1]);//修改i
if(kc[j]=k;
lu=ru;
}
}
printf("%d\n",c[j-1]);
}
return1;
}
6.方块填数
【编程题】(满分33分)
“数独”是当下炙手可热的智力游戏。
一般认为它的起源是“拉丁方块”,是大数学家欧拉于1783年发明的。
如图[1.jpg]所示:
6x6的小格被分为6个部分(图中用不同的颜色区分),每个部分含有6个小格(以下也称为分组)。
开始的时候,某些小格中已经填写了字母(ABCDEF之一)。
需要在所有剩下的小格中补填字母。
全部填好后,必须满足如下约束:
1.所填字母只允许是A,B,C,D,E,F中的某一个。
2.每行的6个小格中,所填写的字母不能重复。
3.每列的6个小格中,所填写的字母不能重复。
4.每个分组(参见图中不同颜色表示)包含的6个小格中,所填写的字母不能重复。
为了表示上的方便,我们用下面的6阶方阵来表示图[1.jpg]对应的分组情况(组号为0~5):
000011
022013
221113
243333
244455
445555
用下面的数据表示其已有字母的填写情况:
02C
03B
05A
20D
35E
53F
很明显,第一列表示行号,第二列表示列号,第三列表示填写的字母。
行号、列号都从0开始计算。
一种可行的填写方案(此题刚好答案唯一)为:
EFCBDA
ACEDFB
DABECF
FBDCAE
BDFAEC
CEAFBD
你的任务是:
编写程序,对一般的拉丁方块问题求解,如果多解,要求找到所有解。
【输入、输出格式要求】
用户首先输入6行数据,表示拉丁方块的分组情况。
接着用户输入一个整数n(n<36),表示接下来的数据行数
接着输入n行数据,每行表示一个预先填写的字母。
程序则输出所有可能的解(各个解间的顺序不重要)。
每个解占用7行。
即,先输出一个整数,表示该解的序号(从1开始),接着输出一个6x6的字母方阵,表示该解。
解的字母之间用空格分开。
如果找不到任何满足条件的解,则输出“无解”
例如:
用户输入:
000011
022013
221113
243333
244455
445555
6
02C
03B
05A
20D
35E
53F
则程序输出:
1
EFCBDA
ACEDFB
DABECF
FBDCAE
BDFAEC
CEAFBD
再如,用户输入:
001111
002113
022243
022443
544433
555553
7
04B
05A
13D
14C
24E
50C
51A
则程序输出:
1
DCEFBA
EFADCB
ABFCED
BEDAFC
FDCBAE
CABEDF
2
DCEFBA
EFADCB
ADFBEC
BECAFD
FBDCAE
CABEDF
3
DCFEBA
AEBDCF
FDACEB
BFEADC
EBCFAD
CADBFE
4
DCFEBA
BEADCF
ADCFEB
FBEADC
EFBCAD
CADBFE
5
DCFEBA
EFADCB
ABCFED
BEDAFC
FDBCAE
CAEBDF
6
DCFEBA
EFADCB
ABDFEC
BECAFD
FDBCAE
CAEBDF
7
DCFEBA
EFADCB
ADBFEC
BECAFD
FBDCAE
CAEBDF
8
DCFEBA
FEADCB
ADBCEF
BFEADC
EBCFAD
CADBFE
9
DCFEBA
FEADCB
AFCBED
BDEAFC
EBDCAF
CABFDE
【注意】
请仔细调试!
您的程序只有能运行出正确结果的时候才有机会得分!
在评卷时使用的输入数据与试卷中给出的实例数据可能是不同的。
请把所有函数写在同一个文件中,调试好后,拷贝到【考生文件夹】下对应题号的“解答.txt”中即可。
相关的工程文件不要拷入。
源代码中不能使用诸如绘图、Win32API、中断调用、硬件操作或与操作系统相关的API。
允许使用STL类库,但不能使用MFC或ATL等非ANSIc++标准的类库。
例如,不能使用CString类型(属于MFC类库);例如,不能使用randomize,random函数(不属于ANSIC++标准)
参考代码:
#include
intlast=36;
chara[6][6]={0};//0表示未填
inthor[6]={0},ver[6]={0};//统计行,列中元素个数
boolcla[6][6]={0};
chargroup[6][7];
intseq=0;
voidoutPut(){
seq++;
printf("%d\n",seq);
for(inti=0;i<6;i++){
for(intj=0;j<5;j++){
printf("%c",a[i][j]);
}
printf("%c\n",a[i][5]);
}
}
voidsearcher(){
inti,j,k,max,x,y;
boolf[6]={0};
if(last==0){
outPut();
return;
}
last--;
//寻找最佳位置
max=-1;
for(i=0;i<6;i++){
if(hor[i]==6)
continue;
for(j=0;j<6;j++)
if(a[i][j]==0&&(hor[i]+ver[j])>max){
max=hor[i]+ver[j];