现在的位置: 首页 > 竞赛 > 正文

2011年软件设计大赛C语言组预赛真题

2012年02月28日 竞赛 ⁄ 共 2216字 ⁄ 字号 暂无评论

2011年 选拔赛 c 高职

下载 2011.预赛.c.高职

考生须知:

考试时间为4小时。

本试卷包含两种题型:“代码填空”与“程序设计”。总计100分。

其中代码填空:3+3+3+5+7+9+12 = 42 分,程序设计:14+17+27 = 58分

1
2
3
4
5
6
7
8
9
10
利息计算
开平方
最小公倍数
求日期差
字符串的轮换
金字塔
中奖计算
程序设计:串的处理
程序设计:画表格
程序设计:5个砝码

填空题要求参赛选手在弄清给定代码工作原理的基础上填写缺失的部分,使得程序逻辑正确、完整。所填写的代码不超过一条语句(即不能出现分号)。

把填空的答案(仅填空处的答案,不包括题面)存入考生文件夹下对应题号的“解答.txt”中即可。

编程题要求选手设计的程序对于给定的输入能给出正确的输出结果。考生的程序只有能运行出正确结果的时候才有机会得分。注意:在评卷时使用的输入数据与试卷中给出的实例数据可能是不同的。选手的程序必须是通用的,不能只对试卷中给定的数据有效。

对每个题目,要求考生把所有函数写在一个文件中。调试好后,存入与考生文件夹下对应题号的“解答.txt”中即可。相关的工程文件不要拷入。

对于编程题目,要求选手给出的解答完全符合ANSI C标准,不能使用c++特性;不能使用诸如绘图、中断调用等硬件相关或操作系统相关的API。

【利息计算】

小李年初在银行存款1千元(一年定期)。他计划每年年底取出100元救助失学儿童。假设银行的存款利率不变,年利率为3%,年底利息自动计入本金。下面的代码计算5年后,该账户上有多少存款。试填写缺失的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
int main(int argc, char *argv[])
{
    double money = 1000;
    int n = 5;
    int i;
    for(i=0; i<n; i++) {
        money = _______________;
        money -= 100;
    }
    printf("%.2f\n", money);
    return 0;
}

【开平方】

如果没有计算器,我们如何求2的平方根?

可以先猜测一个数,比如1.5,然后用2除以这个数字。如果我们猜对了,则除法的结果必然与我们猜测的数字相同。我们猜测的越准确,除法的结果与猜测的数字就越接近。

根据这个原理,只要我们每次取猜测数和试除反馈数的中间值作为新的猜测数,肯定更接近答案!这种计算方法叫做“迭代法”。

下面的代码模拟了如何用手工的方法求2的平方根的过程。请填写缺少的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
int main(int argc, char *argv[])
{
    double n = 2;
    double a = 0;
    double b = n;
    while(fabs(a-b)>1E-15)     {
        a = (a+b)/2;
        b = __________;
    }
 
    printf("%f\n", a);
    return 0;
}

【最小公倍数】

求两个数字的最小公倍数是很常见的运算。比如,3和5的最小公倍是15。6和8的最小公倍数是24。
下面的代码对给定的两个正整数求它的最小公倍数。请填写缺少的代码,使程序尽量高效地运行。

1
2
3
4
5
6
7
int f(int a, int b)
{
    int i;
    for(i=a;  ; ______________ )    {
        if(i%b==0) return i;
    }
}

【日期间隔计算】

人类历史上出现了很多种历法。现行的公历即格里历由儒略历改革而来。它是目前较为精确和规则简明的一种历法,约3300年误差一日。因为闰年问题以及每个月的长度不等,仍然使得某些计算较为麻烦。比如:求两个日期间差多少天。

下面的代码实现了求两个由公历表示的日期间差多少天的功能。其计算原理是先求出每个日期距离1年1月1日的天数差值,再进一步做差即可。请研读代码,填写缺失的部分。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <stdio.h>
typedef struct mydate {
    int year;
    int month;
    int day
} MyDate;
 
int GetAbsDays(MyDate x)
{
    int i;
    int month_day[] = {31,28,31,30,31,30,31,31,30,31,30,31};
    int year = x.year-1;   // 因为欲求距离1年1月1日的距离
    int days = year * 365 + year/4 - year/100 + year/400;
    if(x.year%4==0 && x.year%100!=0 || x.year%400==0)
        month_day[1]++;
    for(i=0; i< _______________________; i++)
        days += month_day[i];
    days += x.day-1;
    return days;
}
 
int GetDiffDays(MyDate a, MyDate b)
{
    return GetAbsDays(b) - GetAbsDays(a);
}
 
int main(int argc, char* argv[])
{
    int n;
    MyDate a =  {1842,5,18};
    MyDate b =  {2000,3,13};
    n = GetDiffDays(a,b);
    printf("%d\n", n);
    return 0;
}

【轮换】

串“abcd”每个字符都向右移位,最右的移动到第一个字符的位置,就变为“dabc”。这称为对串进行位移=1的轮换。同理,“abcd”变为:“cdab”则称为位移=2的轮换。

下面的代码实现了对串s进行位移为n的轮换。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void shift(char* s, int n)
{
    char* p;
    char* q;
    int len = strlen(s);
    if(len==0) return;
    if(n<=0 || n>=len) return;
 
    char* s2 = (char*)malloc(_________);
    p = s;
    q = s2 + n % len;
    while(*p) {
        *q++ = *p++;
        if(q-s2>=len) {
            *q = ___________;
            q = s2;
        }
    }
    strcpy(s,s2);
    free(s2);
}

【金字塔】

下面代码的目标是输出一个大写字母组成的金字塔。其中space表示金字塔底距离左边的空白长度,x表示金字塔底的中心字母。

比如:space=0, x=’C’,则输出:

1
2
3
A
ABA
ABCBA

再如:space=2,x=’E’, 则输出:

  A
  ABA
  ABCBA
  ABCDCBA
  ABCDEDCBA

请分析该段代码的逻辑,填写缺少的部分。

1
2
3
4
5
6
7
8
9
10
void h(int space, char x)
{
    int i;
    if(x<'A' || x>'Z') return;
    ______________;
    for(i=0; i<space; i++) printf(" ");
    for(i=0; i<x-'A'; i++) printf("%c",'A'+i);
    for(i=0; i<=x-'A'; i++) printf("%c",________);
    printf("\n");
}

【中奖计算】

某抽奖活动的规则是:每位参与者在纸上写下一个8位数的号码。最后通过摇奖的办法随机产生一个8位数字。参与者写下的数字中最多有多少个连续位与开奖号码中的相同,则称为中了几个号。

例如:小张写的数字是:12345678,而开奖号码是:42347856。则称小张中了3个号,因为其中最长的相同连续位是:“234”。如果小张写的是:87654321,则他只中了一个号。
下面的代码根据传入的参数,返回中了几个号。其中:a表示被评价的号码,b表示摇号产生的数字。请填写缺少的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int g(int a, int b)
{
    char sa[]="00000000";
    char sb[]="00000000";
    char t;
    int n = 0;
    int i,j;
    sprintf(sa,"%8d", a);
    sprintf(sb,"%8d", b);
    for(i=0; i<8; i++)    {
        for(j=1; j<=8-i; j++) {
            t = ________;
            sa[i+j] = 0;
            if(strstr(sb, sa+i)) {
                if(j>n) _________;
            }
            sa[i+j] = t;
        }
    }
    return n;
}

【串的处理】

在实际的开发工作中,对字符串的处理是最常见的编程任务。本题目即是要求程序对用户输入的串进行处理。具体规则如下:

  1. 把每个单词的首字母变为大写。
  2. 把数字与字母之间用下划线字符(_)分开,使得更清晰
  3. 把单词中间有多个空格的调整为1个空格。

例如:

用户输入:
you and     me what  cpp2005program
则程序输出:
You And Me What Cpp_2005_program
用户输入:
this is     a      99cat
则程序输出:
This Is A 99_cat

我们假设:用户输入的串中只有小写字母,空格和数字,不含其它的字母或符号。每个单词间由1个或多个空格分隔。
假设用户输入的串长度不超过200个字符。

【画表格】

在图形环境中很容易做出漂亮的表格。但在控制台环境中就比较困难了。有的时候可以用一些符号大略地模拟:(word文档中可能不整齐,拷贝到记事本中看)

+-------+------+
|abc    |xyz=tt|
+-------+------+
|hellomm|t2    |
+-------+------+

本题目要求设计一个程序,把用户输入的内容用这种“准表格”的方式展现出来。具体的要求是:

用户输入的第一行是一个整数,表示接下来有多少行信息。接下来的每行由若干单元组成。单元间用逗号分开。

程序输出:用表格方式重新展现的输入内容。

例如:

用户输入:

3

cat,dog,good-luck

1,2,5

do not use,,that

则程序输出:(word文档中可能不整齐,拷贝到记事本中看)

+----------+---+---------+

|cat       |dog|good-luck|

+----------+---+---------+

|1         |2  |5        |

+----------+---+---------+

|do not use|   |that     |

+----------+---+---------+

从中不难看出:

两个连续的逗号表示中间有一个内容为空的单元
列的数目由最大的单元数的那行决定
列的宽度由同列的最宽的单元决定
单元格中的信息左对齐

 

可以假设:用户输入的最大行数为30,可能的最多列数为40。

 

 

【5个砝码】

用天平称重时,我们希望用尽可能少的砝码组合称出尽可能多的重量。

如果只有5个砝码,重量分别是1,3,9,27,81。则它们可以组合称出1到121之间任意整数重量(砝码允许放在左右两个盘中)。
本题目要求编程实现:对用户给定的重量,给出砝码组合方案。

例如:
用户输入:
5
程序输出:
9-3-1
用户输入:
19

程序输出:
27-9+1

要求程序输出的组合总是大数在前小数在后。
可以假设用户的输入的数字符合范围1~121。

抱歉!评论已关闭.