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

第9周编程题在线测试

NOTE:

  1. 要输出一个变量的地址值时,要用格式转换说明符 %p
  2. 空指针 ,即值为NULL的值,是无效指针。
  3. p = 0 和p = NULL 的区别:p = NULL可以明确说明p是指针变量,而不是一个数值变量,而且空指针并不一定就是指向地址为0的存储单元的指针,并非所有编译器都是用0地址。
  4. warning: 每次用指针时都要对其进行初始化!!!
  5. 判断素数的时候注意:对于double类型变量x(不是整型)不能执行求余运算,即不能用 x % i == 0来判断x是否能被i整除,可以使用 x / i == (int)(x/i)来判断x是否能被i整除。

1. 重复数字检查

题目内容:
从键盘输入一个数,检查这个数中是否有重复出现的数字。如果这个数中有重复出现的数字,则显示“Repeated digit!”;否则显示“No repeated digit!”。

函数原型: int CountRepeatNum(int count[], int n);

注: 若有重复数字,则该函数返回重复出现的数字;否则返回-1.

#include<stdio.h>
#define N 10
int CountRepeatNum(int count[], int n);
int main()
{
    int count[N] = {0};
    int n;
    printf("Input n:\n");
    scanf("%d",&n);
    if(CountRepeatNum(count,n) == -1)
        printf("No repeated digit!\n");//返回-1,没有重复数字

    else
        printf("%d is Repeated digit!\n",CountRepeatNum(count,n));//返回重复数字

    return 0;
}

int CountRepeatNum(int count[], int n)
{
    int i = 0,digit = 0;
    int cnt = 0;
    while(n != 0)
    {
        count[i] = n%10;
        n = n/10;
        i++;
    }
    int a[10] = {0};
    for(int j = 0;j < i; j++)
    {
        a[count[j]]++;
    }
    for(int k = 0;k < 10; k++)
    {
        if(a[k] != 0)
            cnt++;
    }

    if(cnt == i)
        return -1;
    else
    {
        for(int p = 0;p < 10; p++)
        {
            if(a[p] > 1)
            return p;
        }
    }
}

2. 教授的课

题目内容:
教授正在为一个有N个学生的班级讲授离散数学课。他对某些学生缺乏纪律性很不满意,于是决定:如果课程开始后上课的人数小于K,就取消这门课程。从键盘输入每个学生的到达时间,请编程确定该课程是否被取消。如果该门课程被取消,则输出“Yes”,否则输出“No”。假设教授在时刻0开始上课。如果一个学生的到达时间是非正整数,则表示该学生在上课前进入教室。如果一个学生的到达时间是正整数,则表示该学生在上课后进入教室。如果一个学生在时刻0进入教室,也被认为是在上课前进入教室。假设到达时间的绝对值不超过100,学生数N不超过1000。要求在输入学生的到达时间之前,先输入N和K。

函数原型: int IsCancel(int a[], int n, int k);

注: 函数功能:根据数组a中记录的学生到达时间确定课程是否被取消,取消则返回1,否则返回0

#include<stdio.h>
#define N 1000
int IsCancel(int a[], int n, int k);
int main()
{
    int n,k;
    int a[N] = {0};
    printf("Input n,k:\n");
    scanf("%d,%d",&n,&k);
    getchar();
    for(int i = 0;i < n; i++)
        scanf("%d",&a[i]);
    if(IsCancel(a,n,k))
        printf("YES\n");
    else
        printf("NO\n");
    return 0;
}

int IsCancel(int a[], int n, int k)
{
    int count = 0;
    for(int i = 0;i < n; i++)
    {
        if(a[i] <= 0)
            count++;
    }
    if(count < k)return 1;
    else return 0;
}

3. 寻找鞍点

题目内容:
请编程找出一个M*N矩阵中的鞍点,即该位置上的元素是该行上的最大值,是该列上的最小值。如果矩阵中没有鞍点,则输出“No saddle point!”

函数原型: void FindSaddlePoint(int a[][N], int m, int n);

注: 在该函数中输出有无鞍点的信息。

#include<stdio.h>
#define N 100
void FindSaddlePoint(int a[][N], int m, int n);
int main()
{
    int m,n;
    int a[N][N];
    printf("Input m,n:\n");
    scanf("%d,%d",&m,&n);
    printf("Input matrix:\n");
    for(int i = 0;i < m; i++)
        for(int j = 0;j < n; j++)
            scanf("%d",&a[i][j]);
    FindSaddlePoint(a,m,n);
    return 0;
}

void FindSaddlePoint(int a[][N], int m, int n)
{
    int i,j;
    for(i = 0;i < m; i++)
    {
        int maxpos = 0;
        int flag = 0;
        for(int k = 0;k < n; k++)
        {
            if(a[i][k] > a[i][maxpos])
                maxpos = k;
        }
        for(int p = 0;p < m; p++)
        {
            if(a[p][maxpos] < a[i][maxpos])
                flag = 1;
        }
        if(flag == 1&& i != m - 1)continue;
        else if(flag == 1 && i == m - 1)
            printf("No saddle point!\n");
        else
            {
                printf("a[%d][%d] is %d\n",i,maxpos,a[i][maxpos]);
                break;
            }
    }

}


4. 计算三位阶乘和数

题目内容:
试求出所有三位阶乘和数:m=a!+b!+c!(其中a为百位数字,b为十位数字,c为个位数字。约定0!=1,并输出所有的m)

#include<stdio.h>
int fact(int n)
{
    if(n == 0)return 1;
    else
        return fact(n - 1)*n;
}
int main()
{
    int a, b, c , i;
    for(i = 100; i <= 999; i++)
    {
        a = i/100;
        b = (i/10)%10;
        c = i%10;
        if(i == fact(a) + fact(b) + fact(c))
        printf("%d\n",i);
    }
    return 0;
}

第9周练兵区编程题

1. 二分法求根

题目内容:
用二分法求下面方程的根

x^3-x-1=0

用二分法求方程的根的基本原理是:若函数有实根,则函数曲线应当在根x*这一点上与x轴有一个交点,并且由于函数是单调的,在根附近的左右区间内,函数值的符号应当相反。利用这一特点,可以通过不断将求根区间二分的方法,每次将求根区间缩小为原来的一半,在新的折半后的区间内继续搜索方程的根,对根所在区间继续二分,直到求出方程的根为止。

#include<stdio.h>
#include<math.h>
float fun(float x)
{
    return x*x*x - x - 1;
}
int main()
{
    float x0,x1,mid;
    scanf("%f,%f",&x0,&x1);
    mid = (x0 + x1)/2;
    if(fun(mid) == 0)
        printf("x=%6.2f\n",mid);
    else
    {
        do
        {
           if(fun(x0)*fun(mid) < 0)
            {
                x1 = mid;
                mid = (x0 + x1)/2;
            }
            else
            {
                x0 = mid;
                mid = (x0 + x1)/2;
            }
        }while(fabs(fun(mid)) > 1e-6);
        printf("x=%6.2f\n",mid);
    }
    return 0;
}

2. 矩阵转置

题目内容:
某二维数组存放的数据构成一个nn的方阵,其中n<=5。写程序,从键盘输入n的值(n<=5),该nn矩阵中各元素的值按下面的公式计算:

a[i][j] = i * n + j + 1

其中,a[i][j]表示第i行第j列的元素。要求分别输出该矩阵和它的转置矩阵。

注意:定义数字大小N时,请用 #define N 10

#include<stdio.h>
#define N 10
int main()
{
    int a[N][N] = {0};
    int n;
    scanf("%d",&n);
    for(int i = 0; i < n; i++)
    {
        for(int  j = 0; j < n; j++)
        {
            a[i][j] = i * n + j + 1;
        }
    }
    printf("The original matrix is:\n");
    for(int i = 0; i < n; i++)
    {
        for(int  j = 0; j < n; j++)
        {
            printf("%3d",a[i][j]);
        }
        printf("\n");
    }
    printf("The changed matrix is:\n");
    for(int i = 0; i < n; i++)
    {
        for(int  j = 0; j < n; j++)
        {
            printf("%3d",a[j][i]);
        }
        printf("\n");
    }
    return 0;
}

3. 程序改错

题目内容:
下面程序的功能是从键盘任意输入n个数,然后找出其中的最大数与最小数,并将其位置对换。目前程序中存在错误,请修改正确。并按照给出的程序运行结果示例检查修改后的程序。

#include  <stdio.h>
#define ARR_SIZE 10
void  MaxMinExchang(int *a, int n);
int main()
{
     int a[ARR_SIZE], i, n;
     printf("Input n(n<=10):\n");
     scanf("%d", &n);
     printf("Input %d Numbers:\n", n);
     for (i=0; i<n; i++)
     {
        scanf("%d", &a[i]);
     }
     MaxMinExchang(a, n);
    printf("After MaxMinExchange:\n");
     for (i=0; i<n; i++)
     {
        printf("%d ", a[i]);
     }
    printf("\n");
    return 0;
}
void  MaxMinExchang(int *a, int n)
{
     int  maxValue = a[0], minValue = a[0], maxPos = 0, minPos = 0;
     int  i, temp;
     for (i=0; i<n; i++)
{
    if (a[i] > maxValue)
    {
        maxValue = a[i];
        maxPos = i;
    }
    if (a[i] < minValue)
    {
        minValue = a[i];
        minPos = i;
    }
}
     temp = a[maxPos];
     a[maxPos] = a[minPos];
     a[minPos] = temp;
}

4. 蛇形矩阵

题目内容:
从键盘任意输入一个自然数n(n表示矩阵的大小,假设不超过100),请编程输出一个n*n的蛇形矩阵。如果输入的n不是自然数或者输入了不合法的数字,则输出"Input error!"。

函数原型: void ZigzagMatrix(int a[][N], int n);

函数功能: 计算n*n的蛇形矩阵

提示: 用两个双重循环分别计算n*n矩阵的左上三角和右下三角,设置一个计数器从1开始记录当前要写入矩阵的元素值,每次写完一个计数器加1,在计算左上角和右下角矩阵元素时,分奇数和偶数两种情况考虑待写入的元素在矩阵中的行列下标位置。

#include<stdio.h>
#define N 100
int main()
{
    int a[N][N]={0};
    int n,ret,i,j,count = 1;
    printf("Input n:\n");
    ret = scanf("%d",&n);
    if(ret != 1 || n < 0 || n > 100)
        printf("Input error!\n");
    for(i = 0;i < n; i++) //左上三角,包括对角线,用i来控制行和列的和
    {
        if(i%2 == 0)  	  //分奇偶,走向会不同
        {
            for(j = i; j >= 0; j--)
            {
                a[j][i - j] = count;
                count++;
            }
        }
        else
        {
            for(j = 0; j <= i; j++)
            {
                a[j][i - j] = count;
                 count++;
            }
        }
    }
    int end = 1;
    for(;i <= (n - 1)*2; i++) //右下三角,用i控制行和列的和
    {
        if(i%2 == 1)
        {
            for(j = n - 1;j >= end; j--)
            {
                a[i - j][j] = count;
                count++;
            }
        }
        else
        {
            for(j = n - 1;j >= end; j--)
            {
                a[j][i - j] = count;
                count++;
            }
        }
        end++;
    }
    for(int k = 0; k < n; k++)
    {
        for(int m = 0; m < n; m++)
        {
            printf("%4d",a[k][m]);
        }
        printf("\n");
    }
}

5. 亲密数_1

题目内容:
相亲数,也称为亲密数,如果整数A的全部因子(包括1,不包括A本身)之和等于B,且整数B的全部因子(包括1,不包括B本身)之和等于A,则将整数A和B称为亲密数。

从键盘任意输入两个整数m和n,编程判断m和n是否是亲密数。若是亲密数,则输出“Yes!”,否则输出“No!”

#include<stdio.h>
int SumFactor(int n);
int main()
{
    int m,n;
    printf("Input m, n:\n");
    scanf("%d,%d",&m,&n);
    if(m == SumFactor(n) && n == SumFactor(m))
        printf("Yes!\n");
    else
        printf("No!\n");
    return 0;
}

int SumFactor(int n)
{
    int sum = 0;
    for(int i = 1;i < n; i++)\
    {
        if(n%i == 0)
            sum += i;
    }
    return sum;
}

6. 亲密数_2

题目内容:
从键盘任意输入一个整数n,编程计算并输出n以内的全部亲密数。

#include<stdio.h>
int SumFactor(int n);
int main()
{
    int n,i,j;
    printf("Input n:\n");
    scanf("%d",&n);
    for(i = 200;i < n; i++)
    {
        j = SumFactor(i);
        if(i == SumFactor(j)&& i < j)
            printf("(%d,%d)\n",i,j);
    }
    return 0;
}

int SumFactor(int n)
{
    int sum = 0;
    for(int i = 1;i < n; i++)\
    {
        if(n%i == 0)
            sum += i;
    }
    return sum;
}

7. 完全数

题目内容:
完全数(Perfect Number),又称完美数或完数,它是指这样的一些特殊的自然数。它所有的真因子(即除了自身以外的约数)的和,恰好等于它本身,即m的所有小于m的不同因子(包括1)加起来恰好等于m本身。注意:1没有真因子,所以1不是完全数。计算机已经证实在10300以下,没有奇数的完全数。例如,因为6 = 1 + 2 + 3,所以6是一个完全数。

从键盘任意输入一个整数m,编程判断m是否是完全数。若m是完全数,则输出“Yes!”,并同时打印出每一个完美数的全部因子,以验证这个数确实是一个完美数。若m不是完全数,则输出“No!”

#include<stdio.h>
int IsPerfect(int m);
int main()
{
    int m;
    printf("Input m:\n");
    scanf("%d",&m);
    if(!IsPerfect(m))
        printf("No!\n");
    else
    {
        printf("Yes!\n");
        printf("1");
        for(int j = 2;j < m; j++)
        {
            if(m%j == 0)
                printf(",%d",j);
        }
    }
    return 0;
}

int IsPerfect(int m)
{
    int sum = 0;
    for(int i = 1;i < m; i++)
    {
        if(m%i == 0)
            sum += i;
    }
    if(sum != m)
        return 0;
    else
        return 1;

}

8. 回文素数

题目内容:
所谓回文素数是指对一个素数n,从左到右和从右到左读是相同的,这样的数就称为回文素数,例如11,101,313等。编程计算并输出不超过n(100<=n<1000)的回文素数,并统计这些回文素数的个数,其中n的值从键盘输入。

#include<stdio.h>
#include<math.h>
#define N 100
int IsBackPrime(int n);
int IsPrime(int n);
int main()
{
    int n,count = 0;
    printf("Input n:\n");
    scanf("%d",&n);
    for(int  i = 10; i <= n; i++)
    {
        if(IsBackPrime(i))
        {
            printf("%4d",i);
            count++;
        }
    }
    printf("\ncount=%d\n",count);
    return 0;
}
int IsPrime(int n)
{
    for(int i = 2;i <= sqrt(n); i++)
    {
        if(n%i == 0)
            return 0;
    }
    return 1;
}
int IsBackPrime(int n)
{
    int a[N] = {0};
    int j = 0;
    int low = 0,high;
    if(IsPrime(n) == 0)
        return 0;
    while(n)
    {
            a[j] = n%10;
            n = n/10;
            j++;
    }
    high = j - 1;
    while(low < high)
    {
        if(a[low] != a[high])
            return 0;
        low++;
        high--;
    }
    return 1;
}

9. 梅森尼数

题目内容:
形如 2^i-1 的素数,称为梅森尼数。编程计算并输出指数i在[2,n]中的所有梅森尼数,并统计这些梅森尼数的个数,其中n的值由键盘输入,并且n的值不能大于50。其中,2^i 表示2的i次方,请不要使用pow(2,i)编程计算,应采用循环累乘求积的方式计算2^i。
提示: 当i 超过30以后,2^i-1的值会很大,不能用long型变量来存储,必须使用double类型来存储。对于double类型变量x(不是整型)不能执行求余运算,即不能用 x % i == 0来判断x是否能被i整除,可以使用 x / i == (int)(x/i)来判断x是否能被i整除。

#include<stdio.h>
#include<math.h>
#define N 100
int IsMersenne(int i,double *sum);
int IsPrime(double n);
int main()
{
    int count = 0,n;
    double sum[1] = {0};
    printf("Input n:\n");
    scanf("%d",&n);
    for(int i = 1; i < n; i++)
    {
        if(IsMersenne(i,&sum))
        {
            printf("2^%d-1=%.0lf\n",i,sum[0] - 1);
            count++;
        }
    }
    printf("count=%d\n",count);
    return 0;
}
int IsPrime(double n)
{
    if(n == 1)
        return 0;
    for(int i = 2;i <= sqrt(n); i++)
    {
        if(n/i == (int)(n/i))
            return 0;
    }
    return 1;
}

int IsMersenne(int i,double *sum)
{
    double n;
    sum[0] = 1;
    for(int j = 1; j <= i; j++)
    {
        sum[0] = sum[0] * 2;
    }
    if(IsPrime(sum[0] - 1))
        return 1;
    else
        return 0;
}

10. 工资统计

题目内容:
某公司有职员(最多50人),试编写程序打印最高工资、最低工资和平均工资。公司人数在主函数给出,职工工资输入请调用Input函数,计算最高工资、最低工资和平均工资调用Compute函数,打印最高工资、最低工资和平均工资在主函数。请在给定的框架下写出完整程序。

#include<stdio.h>
void Input(float wage[], int n);
float Compute(float wage[], int n, float *pmaxwage, float *pminwage);
int main()
{
    float wage[50],maxwage,minwage,avewage;
    int n;
    printf("Please input n:\n");
    scanf("%d",&n);
    Input(wage,n);
    avewage=Compute(wage,n,&maxwage,&minwage);
    printf("maxwage=%.2f, minwage=%.2f, avewage=%.2f\n",maxwage,minwage,avewage);
    return 0;
}

void Input(float wage[], int n)
{   int i;
    for(i = 0;i < n; i++)
    {
        scanf("%f",&wage[i]);
    }
}

float Compute(float wage[], int n, float *pmaxwage, float *pminwage)
{
    int  i;
    *pmaxwage = wage[0];
    *pminwage = wage[0];
    float sumwage = 0;
    for(i = 0;i < n; i++)
    {
        if(wage[i] > *pmaxwage)
			*pmaxwage = wage[i];
        if(wage[i] < *pminwage)
            *pminwage = wage[i];
        sumwage += wage[i];
    }
    return sumwage/n;
}

  • 7
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言程序设计精髓MOOC》第三主要内容是关于指针和数组的学习。 首先是指针的介绍和使用。指针是C语言中一个非常重要的概念,它可以用来间接访问内存中的数据,通过指针可以实现对变量地址的操作。在学习过程中,我们了解了指针的定义和声明,以及指针与数组之间的关系。指针在程序设计中的应用非常广泛,特别是在动态内存分配和函数调用等方面,有着重要的作用。 其次是数组的使用。数组是一种由相同类型的元素组成的集合,它在C语言中非常常用。在第三的学习中,我们了解了数组的定义、初始化和遍历等基本操作,还学习了一些在数组中常用的算法和技巧。通过多维数组和指针数组的学习,我们可以更灵活地处理多个数据。 除了指针和数组,第三还涉及到了C语言中的结构体(struct)和文件的输入输出操作等内容。结构体是一种可以封装多个不同类型的数据的自定义数据类型,它在实际的程序设计中经常被用于组织和管理数据。文件的输入输出操作涉及了C语言中如何读写文件以及相关的文件处理函数等知识点。 通过学习《C语言程序设计精髓MOOC》第三的内容,我们对指针和数组有了更深入的认识,并且掌握了它们的基本用法和应用技巧。这对于进一步学习和理解C语言程序设计以及其他高级编程语言都非常有帮助。此外,通过作业和练习的完成,我们可以检验和巩固所学的知识,提高我们自己的编程能力。希望通过这门课程的学习,能够让我们对C语言有更全面和深入的了解,为以后的学习和工作打下坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值