C语言程序设计精髓(MOOC第11周 )题

第11周编程题在线测试

NOTE:

  • 指针变量:保存地址型数据,必须初始化才能使用,否则会指向不确定的存储单元。
  • &a[i] 等于 *(a + i)
  • ‘^’ 异或操作:0和任何数异或等于本身;1和任何数异或取相反数;数自己和自己异或等于0。
  • 二维数组a[N][N]中,a代表二维数组的首地址,第0行的地址,行地址,a + i代表第i行的首地址,并非表示&a[0][i]。
  • int (* p) [3] 定义的是行指针,基类型为“int[3]型”,意思是指向一个含有3个整型元素的数组的指针 a[i][j] 等于 *( *(a + i) + j ) ,与此易混淆的是 int * p[3] 这个定义的是一个指针数组,同理,对于函数定义 int * p( ) 返回的是int * 型,而int ( *p)( )返回值为整型,其中 指针变量p指向返回值为整型的函数。、
  • int *p = *a; //a[0] 定义的是列指针;a[i][j] 等于 *( p + i * n + j)。
  • 关于main函数中的命令行参数:我们知道C99标准中对于main函数的正确写法只有两种,吐槽一下老谭酸菜程序设计面=-=,言归正传,请看下面:
int main(void) //不带参数的main函数
{
    //TODO
    return 0;
}
int main(int argc, char* argv[]) //带参数的main函数
{
    //TODO
    return 0;
}

从第二个带参数的main函数中可以看到,第一个参数为int型的变量,大小为命令行参数的个数,第二个参数为指向字符串的指针数组,其中argv[0]为自身.c文件编译后的可执行文件.exe的路径,其余的需要自己定义,比如在CodeBlocks下可以在Project–>Set programs’ arguments弹出的对话框中设置。


1. 山地训练

题目内容:
为了能在下一次跑步比赛中有好的发挥,小白在一条山路上开始了她的跑步训练。她希望能在每次训练中跑得尽可能远,不过她也知道农场中的一条规定:女孩子独自进山的时间不得超过M秒(1 <= M <= 10,000,000)。假设整条山路划分成T个长度相同的路段(1 <= T <= 100,000),并且小白用si表示第i个路段的路况,用u、f、d这3个字母分别表示第i个路段是上坡、平地、下坡。小白跑完一段上坡路的耗时是U秒(1 <= U <= 100),跑完一段平地的耗时是F秒(1 <= F <= 100),跑完一段下坡路的耗时是D秒(1 <= D <= 100)。注意,沿山路原路返回时,原本是上坡的路段变成了下坡路段,原本是下坡的路段变成了上坡路段。小白想知道,在能按时返回农场的前提下,她最多能在这条山路上跑多少个路段。请你编程帮助她计算。

函数原型: long Fun(long M, long T, long U, long F, long D, char str[]);

函数功能: 计算在限时M秒内T个路段的情况下,最多往返可跑的路段数。 参数:M,T,U,F,D分别代表限时、路段数,以及上坡、平地、下坡的耗时,数组str保存整条山路的路段状况,返回值:最多可跑的路段数。

#include
#include
long Fun(long M, long T, long U, long F, long D, char str[]);
int main(void)
{
    long M, T, U, F, D, num;
    char str[100000];
    printf( "Input M,T,U,F,D:");
    scanf("%ld%ld%ld%ld%ld",&M,&T,&U,&F,&D);
    printf("Input conditions of road:");
    scanf("%s",str);
    num = Fun(M,T,U,F,D,str);
    printf("num=%ld\n",num);
    return 0;
}

long Fun(long M, long T, long U, long F, long D, char str[])
{
    long i;
    long sum = 0;
    for(i = 0; i < T; i++)
    {
        if(str[i] == 'f')
            sum += 2*F;
        else
            sum += U + D;
        if(sum > M)
            return i;
    }
    return T - 1; //我觉得应该是 8, 怎么会是7呢,这么多时间肯定能跑完啊,有问题
}

2. 奇偶数分离

题目内容:
输入n个整数(n从键盘输入,假设n的值不超过100),按奇偶数分成两组并输出。输出两行,第一行为所有奇数,第二行为所有偶数,保持数据的相对顺序与输入顺序相同。

函数原型: void Seperate(int a[], int n); //数组a[]存放用户输入的n个整数

解题思路: 用两个循环分别输出奇数和偶数,在输出第一个数时用"%d"格式字符,在输出其余数时用",%d"格式字符,用标志变量记录和判断是否是第一个奇数或偶数。

#include
#define N 100
void Seperate(int a[], int n);
int main(void)
{
    int n;
    int a[N] = {0};
    printf("Input n:");
    scanf("%d", &n);
    printf("Input numbers:");
    for(int i = 0; i < n; i++)
        scanf("%d",&a[i]);
    Seperate(a, n);
    return 0;
}

void Seperate(int a[], int n)
{
    int i, count = 0;
    for(i = 0; i < n; i++)
    {
        if(a[i]%2 == 1)
        {
            if(count == 0)
                printf("%d",a[i]);
            else
                printf(",%d",a[i]);
            count++;
        }
    }
    count = 0;
    printf("\n");
    for(i = 0; i < n; i++)
    {
        if(a[i]%2 == 0)
        {
            if(count == 0)
                printf("%d",a[i]);
            else
                printf(",%d",a[i]);
            count++;
        }
    }
}

3. 子串判断

题目内容:
从键盘输入两个长度小于80的字符串A和B,且A的长度大于B的长度,编程判断B是不是A的子串,如果是,则输出”Yes”,否则输出”No”。这里所谓的该串的子串是指字符串中任意多个连续的字符组成的子序列。

函数原型: int IsSubString(char a[], char b[]);

函数功能: 判断b是否是a的子串,是则返回1,否则返回0

#include
#include
#define N 80
int IsSubString(char a[], char b[]);
int main(void)
{
    char a[N], b[N];
    printf("Input the first string:");
    gets(a);
    printf("Input the second string:");
    gets(b);
    if(IsSubString(a,b))
        printf("Yes\n");
    else
        printf("No\n");
    return 0;
}

int IsSubString(char a[], char b[])
{
    int i, j;
    int alen = strlen(a);
    int blen = strlen(b);
    for(i = 0; i < alen; i++)
    {
        int pos = 0;
        for(j = 0; j < blen; j++)
        {
            if(a[i + pos] == b[j])
                pos++;
        }
        if(pos == blen)
            return 1;
    }
    return 0;
}

4. 星期查找

题目内容:
任意输入英文的星期几,通过查找如图所示的星期表,输出其对应的数字,若查到表尾,仍未找到,则输出错误提示信息。

#include
#include
#define N 20
int main(void)
{
    char weekDay[7][N] = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
    char str[N];
    char (*p)[N] = weekDay;
    printf("Please enter a string:\n");
    gets(str);
    for(int i = 0; i < 7; i++)
    {
        if(strcmp(str,p + i) == 0)
        {
            printf("%s is %d\n",str,i);
            return 0;
        }
    }
    printf("Not found!\n");
    return 0;
}

第11周练兵区编程题

1. 找出按字典顺序排在最前面的国名

题目内容:
输入5个国名,编程找出并输出按字典顺序排在最前面的国名。

#include
#include
#define N 20
int main(void)
{
    char country[5][N];
    char *min = country[0];
    int  i;
    printf("Input five countries' names:\n");
    for(i = 0; i < 5; i++)
        gets(country[i]);
    for(i = 0; i < 5; i++)
    {
        printf("%d\n",strcmp(min,country[i]));
        if(strcmp(min,country[i]) > 0)
            strncpy(min,country[i],sizeof(country[i]));
    }
    printf("The minimum is:%s\n",min);
    return 0;
}

3. 月份表示

题目内容:
用指针数组保存表示每个月份的英文单词以及“Illegal month”的首地址,然后编程实现:从键盘任意输入一个数字表示月份值n,程序输出该月份的英文表示,若n不在1~12之间,则输出“Illegal month”。

#include
#include
#define N 15
int main(void)
{
    char month[13][N] = {"Illegal month", "January", "February", "March", "April", "May",
                         "June", "July", "August", "September", "October", "November", "December"};
    int num;
    printf("Input month number:\n");
    scanf("%d",&num);
    if(num > 12 ||num < 1)
        printf("%s\n",month[0]);
    else
        printf("month %d is %s\n", num, month[num]);
    return 0;
}

4. 程序改错——1

题目内容:
从键盘任意输入m个学生n门课程的成绩,然后计算每个学生各门课的总分sum和平均分aver。下面程序存在极为隐蔽的错误,请分析错误的原因,并修改程序,同时按照给出的程序运行示例检查修改后的程序。

#include  
#define STUD 30            //最多可能的学生人数
#define COURSE 5             //最多可能的考试科目数
void  Total(int *score, int sum[], float aver[], int m, int n);
void  Print(int *score, int sum[], float aver[], int m, int n);
int main(void)
{
         int     i, j, m, n, score[STUD][COURSE], sum[STUD];
         float   aver[STUD];
         printf("Enter the total number of students and courses:\n");
         scanf("%d%d",&m,&n);
         printf("Enter score:\n");
         for (i=0; i<m; i++)
         {
            for (j=0; j<n; j++)
            {
                scanf("%d", &score[i][j]);
            }
        }
        Total(*score, sum, aver, m, n);
        Print(*score, sum, aver, m, n);
        return 0;
}

void  Total(int *score, int sum[], float aver[], int m, int n)
{
        int  i, j;
        for (i=0; i<m; i++)
        {
            sum[i] = 0;
            for (j=0; j<n; j++)
            {
                sum[i] = sum[i] + *(score + i * COURSE + j);
            }
            aver[i] = (float) sum[i] / n;
        }
}

void  Print(int *score, int sum[], float aver[], int m, int n)
{
        int  i, j;
        printf("Result:\n");
        for (i=0; i<m; i++)
        {
            for (j=0; j<n; j++)
            {
                printf("%4d\t", *(score + i * COURSE + j));
            }
            printf("%5d\t%6.1f\n", sum[i], aver[i]);
     }
}

5. 程序改错——2

题目内容:
下面主函数调用函数SortString()按奥运会参赛国国名在字典中的顺序对其入场次序进行排序,目前程序存在错误,请修改正确,并按照给出的程序运行示例检查修改后的程序。

#include  
#include  
#define   M  150 /* 最多的字符串个数 */
#define   N  10 /* 字符串最大长度 */
void SortString(char *ptr[], int n);
int main()
{
  int    i, n;
  char   str[M][N];
  char   *pStr[M];
  for(int i = 0; i < M; i++)
    pStr[i] = str[i];
  printf("How many countries?\n");
  scanf("%d",&n);
  getchar();        /* 读走输入缓冲区中的回车符 */
  printf("Input their names:\n");
  for (i=0; i<n; i++)
  {
      gets(pStr[i]);  /* 输入n个字符串 */
  }
  SortString(pStr, n); /* 字符串按字典顺序排序 */
  printf("Sorted results:\n");
  for (i=0; i<n; i++)
  {
      puts(pStr[i]);  /* 输出排序后的n个字符串 */
  }
  return 0;
}
void SortString(char *ptr[], int n)
{
  int   i, j;
  char  *temp = NULL;
  for (i=0; i<n-1; i++)
  {
      for (j=i+1; j<n; j++)
      {
         if (strcmp(ptr[j], ptr[i]) < 0)
         {

              temp = ptr[i];
              ptr[i] = ptr[j];
              ptr[j] = temp;
         }
      }
  }
}

6. 找数组最值

题目内容:
按如下函数原型编程从键盘输入一个m行n列的二维数组,然后计算数组中元素的最大值及其所在的行列下标值。其中,m和n的值由用户键盘输入。已知m和n的值都不超过10。

void InputArray(int *p, int m, int n);

int FindMax(int *p, int m, int n, int *pRow, int *pCol);

#include
#define N 10
void InputArray(int *p, int m, int n);
int  FindMax(int *p, int m, int n, int *pRow, int *pCol);
int main(void)
{
    int num[N][N] = {0};
    int m, n, ret, prow, pcol;
    printf( "Input m,n:\n");
    scanf("%d,%d",&m,&n);
    int *p = *num;
    InputArray(p,m,n);
    ret = FindMax(p, m, n, &prow, &pcol);
    printf("max=%d,row=%d,col=%d\n", ret, prow, pcol);
    return 0;
}

void InputArray(int *p, int m, int n)
{
    int i, j;
    printf( "Input %d*%d array:\n",m,n);
    for(i = 0; i < m; i++)
    {
        for(j = 0; j < n; j++)
        {
            scanf("%d",p + i*N + j);
        }
    }
}

int  FindMax(int *p, int m, int n, int *pRow, int *pCol)
{
    *pRow = 0;
    *pCol = 0;
    int max = *p;
    for(int i = 0; i < m; i++)
        for(int j = 0; j < n; j++)
        {
            if(max < *(p + i*N + j))
            {
                *pRow = i;
                *pCol = j;
                max = *(p + i*N +j);
            }
        }
        return max;
}

7. 冒泡排序

题目内容:
采用冒泡法进行升序排序法的基本原理是:对数组中的n个数执行n-1遍检查操作,在每一遍执行时,对数组中剩余的尚未排好序的元素进行如下操作:对相邻的两个元素进行比较,若排在后面的数小于排在前面的数,则交换其位置,这样每一遍操作中都将参与比较的数中的最大的数沉到数组的底部,经过n-1遍操作后就将全部n个数按从小到大的顺序排好序了。

#include
void BubbleSort(int a[],int n);
int main(void)
{
    int n;
    printf("Input n:");
    scanf("%d", &n);
    int a[n];
    printf("Input %d numbers:", n);
    for(int i = 0; i < n; i++)
        scanf("%d",&a[i]);
    BubbleSort(a, n);
    printf("Sorting results:");
    for(int i = 0; i < n; i++)
        printf("%4d", *(a + i));
    return 0;
}

void BubbleSort(int a[],int n)
{
    int i, j;
    int flag;
    for(i = 0; i < n - 1 ; i++)
    {
        flag = 0;
        for(j = 0; j < n - 1; j++)
        {
            if(*(a + j) > *(a + j + 1))
            {
                flag = 1;
                int temp;
                temp = *(a + j);
                *(a + j) = *(a + j + 1);
                *(a + j + 1) = temp;
            }
        }
        if(flag == 0)
            break;
    }
}

8. 删除字符串中与某字符相同的字符

题目内容:
在字符串中删除与某字符相同的字符,要求用字符数组作函数参数。

#include
#include
#define N 100
void Delete_X(char *str,char *pstr, char ch);
int main(void)
{
    char str[N],pstr[N];
    char *fir = str;
    char *sec = pstr;
    char ch;
    memset(str,'\0',sizeof(str));
    memset(pstr,'\0',sizeof(pstr));
    printf("Input a string:\n");
    gets(fir);
    printf("Input a character:\n");
    ch = getchar();
    Delete_X(fir,sec,ch);
    printf("Results:%s\n",pstr);
    return 0;
}

void Delete_X(char *str,char *pstr,char ch)
{
    int i = 0, j = 0;
    char *fir = str;
    char *sec = pstr;
    while(*(fir + i) != '\0')
    {
        if(*(fir + i) != ch)
        {
            *(sec + j) = *(fir + i);
            j++;
        }
        i++;
    }
}

9. 求最大数和最小数的最大公约数

题目内容:
从键盘输入10个正整数,求出最大数,最小数,以及他们的最大公约数。要求用数组实现。

#include
int gcd(int a,int b);
void Find_max_min(int a[],int *max,int *min);
int main(void)
{
    int num[10] = {0};
    int max,min,ret;
    printf("Input 10 numbers:\n");
    for(int i = 0; i < 10; i++)
        scanf("%d",&num[i]);

    Find_max_min(num,&max,&min);
    ret = gcd(max,min);
    printf("maxNum=%d\n",max);
    printf("minNum=%d\n",min);
    if(ret)
    printf("%d",ret);
    return 0;
}

int gcd(int a,int b)
{
    int r;
    if(a > 0 && b > 0)
    {
        while(b != 0)
        {
            r = a%b;
            a = b;
            b = r;
        }
        return a;
    }
    else
        return 0;

}

void Find_max_min(int a[],int *max,int *min)
{
    *max = a[0];
    *min = a[0];
    for(int i = 0; i < 10; i++)
    {
        if(*max < a[i])
        {
            *max = a[i];
        }
        if(*min > a[i])
        {
            *min = a[i];
        }
    }
}

10. 数列合并

题目内容:
已知两个不同长度的降序排列的数列(假设序列的长度都不超过5),请编程将其合并为一个数列,使合并后的数列仍保持降序排列。

函数原型: void Merge(int a[], int b[], int c[], int m, int n);

函数功能: 将两个长度分别为m和n、降序排列的子序列a和b合并后放到数组c中

#include
#define N 5
void Merge(int a[], int b[], int c[], int m, int n);
int main(void)
{
    int m,n;
    int a[N] = {0};
    int b[N] = {0};
    int c[N*2] = {0};
    printf("Input m,n:");
    scanf("%d,%d", &m, &n);
    printf("Input array a:");

    for(int i = 0; i < m; i++)
        scanf("%d",&a[i]);

    printf("Input array b:");

    for(int i = 0; i < n; i++)
        scanf("%d", &b[i]);

    Merge(a,b,c,m,n);

    for(int i = 0; i <(m + n); i++)
        printf("%4d",c[i]);

    return 0;
}

void Merge(int a[], int b[], int c[], int m, int n)
{
    int i = 0;
    int j = 0;
    int k = 0;
    while(i < m && j < n)
    {
        if(a[i] >= b[j])
        {
            c[k++] = a[i++];
        }
        else
        {
            c[k++] = b[j++];
        }
    }

    while(i < m)
        c[k++] = a[i++];

    while(j < n)
        c[k++] = b[j++];
}

你可能感兴趣的:(C语言程序设计精髓(MOOC第11周 )题)