MOOC哈工大2020C语言程序设计精髓练兵区编程题第八周

1 三天打渔两天晒网(4分)

题目内容:

中国有句俗语叫“三天打鱼两天晒网”,某人从1990年1月1日起开始“三天打鱼两天晒网”,即工作三天,然后再休息两天。问这个人在以后的某一天中是在工作还是在休息。从键盘任意输入一天,编程判断他是在工作还是在休息,如果是在工作,则输出:He is working,如果是在休息,则输出:He is having a rest,如果输入的年份小于1990或者输入的月份和日期不合法,则输出:Invalid input。

int IsLeapYear(int year);

int CalculationDays(int year, int month, int day);

int Check(int year, int month, int day);

int main()
{
    int year, month, day, days = 0;
    scanf("%4d-%2d-%2d", &year, &month, &day);
    //检查输入是否有效
    if (!Check(year, month, day))
    {
        printf("Invalid input");
        return 0;
    }
    days = CalculationDays(year, month, day);
    if(days % 5 == 1 || days % 5 == 2  || days % 5 == 3)
    {
        printf("He is working");
    }
    else
    {
        printf("He is having a rest");
    }
    return 0;
}

/**
 * 计算总天数
 * @param month
 * @return
 */
int CalculationDays(int year, int month, int day)
{
    int sum = 0, days = 0;
    // 年份总天数
    for (int i = 1990; i < year; i++)
    {
        //闰年
        if(IsLeapYear(i))
        {
            days++;
        }
        days = days + 365;
    }
    //月份天数
    switch (month) {
        case 1:
            sum = 0;
            break;
        case 2:
            sum = 31;
            break;
        case 3:
            sum = 59;
            break;
        case 4:
            sum = 90;
            break;
        case 5:
            sum = 120;
            break;
        case 6:
            sum = 151;
            break;
        case 7:
            sum = 181;
            break;
        case 8:
            sum = 212;
            break;
        case 9:
            sum = 243;
            break;
        case 10:
            sum = 273;
            break;
        case 11:
            sum = 304;
            break;
        case 12:
            sum = 334;
            break;
    }
    //闰年月天数加一
    if(IsLeapYear(year))
    {
        sum++;
    }
    //年份总天数 + 月份天数 + 多少天
    days = days + sum + day;
    return days;
}

/**
 * 判断闰年
 * @param year 输入年份
 * @return 返回0不是闰年
 */
int IsLeapYear(int year)
{
    if((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
    {
        return 1;
    }
    return 0;
}

/**
 * 检查输入是否有效
 * @param year
 * @param month
 * @param day
 * @return
 */
int Check(int year, int month, int day)
{
    int flag = 1;
    if(year < 1990 || month < 1 || month > 12 || day < 1 || day > 31)
    {
        flag = 0;
    }

    //二月比较特殊
    if (month == 2)
    {
        if(IsLeapYear(year)){
            if(day > 29)
            {
                flag = 0;
            }
        }
        else
        {
            if(day > 28)
            {
                flag = 0;
            }
        }
    }

    //只有30天的月份
    if(month == 4 || month == 6 || month == 9 || month == 11)
    {
        if(day > 30)
        {
            flag = 0;
        }
    }

    return flag;
}

这题用例1没过我很懵逼,3个测试样例输出都没问题

2 统计用户输入(4分)

题目内容:

从键盘读取用户输入直到遇到#字符,编写程序统计读取的空格数目、读取的换行符数目以及读取的所有其他字符数目。(要求用getchar()输入字符)

int main()
{
    int space = 0, newline = 0, others = 0;
    char c;
    printf("Please input a string end by #:\n");
    while (1)
    {
        c = getchar();
        if(c == '#')
        {
            break;
        }
        else if(c == ' ')
        {
            space++;
        }
        else if(c == '\n')
        {
            newline++;
        }
        else
        {
            others++;
        }
    }
    printf("space: %d,newline: %d,others: %d\n", space, newline, others);
    return 0;
}

3 统计正整数中指定数字的个数(4分)

题目内容:

从键盘输入一个正整数number,求其中含有指定数字digit的个数。例如:从键盘输入正整数number=1222,若digit=2,则1223中含有 3个2,要求用函数实现。函数原型为:int CountDigit(int number,int digit);

int CountDigit(int number,int digit);

int main()
{
    int m,n;
    printf("Input m,n:\n");
    scanf("%d,%d", &m, &n);
    printf("%d\n", CountDigit(m, n));
    return 0;
}


int CountDigit(int number,int digit)
{
    int n, count = 0;
    while (number != 0)
    {
       n = number % 10;
       if(n == digit)
       {
           count++;
       }
       number = number / 10;
    }
    return count;
}

4 玫瑰花数(4分)

题目内容:

如果一个n位正整数等于它的n个数字的n次方和,则称该数为n位自方幂数。四位自方幂数称为玫瑰花数。编程计算并输出所有的玫瑰花数。

int main() 
{
    int n, a, b, c, d;
    for ( n = 1000; n < 10000; ++n) 
    {
        a = n / 1000;
        b = n / 100 % 10;
        c = n / 10 % 10;
        d = n % 10;
        if((pow(a, 4) + pow(b, 4) + pow(c, 4) + pow(d, 4)) == n)
        {
            printf("%d\n", n);
        }
    }
    return 0;
}

5 四位反序数(4分)

题目内容:

反序数就是将整数的数字倒过来形成的整数。例如,1234的反序数是4321。设N是一个四位数,它的9倍恰好是其反序数,编程计算并输出N的值。

方法1

int main()
{
    int n, t, s = 0;
    for ( n = 1000; n < 10000; ++n)
    {
        t = n;
        while (t)
        {
            s = s * 10 + (t % 10);
            t = t / 10;
        }
        if(s == n * 9)
        {
            printf("%d\n", n);
        }
        s = 0;
    }
    return 0;
}

方法2

int main()
{
    int n, a, b, c, d;
    for ( n = 1000; n < 10000; ++n)
    {
        a = n / 1000;
        b = n / 100 % 10;
        c = n / 10 % 10;
        d = n % 10;
        if((d * 1000 + c * 100 + b * 10 + a) == n * 9)
        {
            printf("%d\n", n);
        }
    }
    return 0;
}

6 8除不尽的自然数(4分)

题目内容:

一个自然数被8除余1,所得的商被8除也余1,再将第二次的商被8除后余7,最后得到一个商为a。又知这个自然数被17除余4,所得的商被17除余15,最后得到一个商是a的2倍。求满足以上条件的最小自然数。

int main()
{
    int n, a;
    for (n = 0; ; ++n)
    {
        a = (34 * n + 15) * 17 + 4;
        if(((n * 8 + 7) * 8 + 1) * 8 + 1 == a)
        {
            printf("%d\n", a);
            break;
        }
    }
    return 0;
}

7 矩阵转置v1.0(4分)

题目内容:

用二维数组作为函数参数,编程计算并输出n×n阶矩阵的转置矩阵。其中,n的值不超过10,n的值由用户从键盘输入。

#define N 10

void ReadNumber(int a[N][N], int n);

void MatrixTransposed(int arr[N][N], int n);

int main()
{
    int arr[N][N], n;
    printf("Input n:");
    scanf("%d", &n);
    printf("Input %d*%d matrix:\n", n, n);
    ReadNumber(arr,n);
    printf("The transposed matrix is:\n");
    MatrixTransposed(arr,n);
    return 0;
}

void ReadNumber(int arr[N][N],int n)
{
    int i, j;
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            scanf("%d",&arr[i][j]);
        }
        getchar();
    }
}

void MatrixTransposed(int arr[N][N], int n)
{
    int i,j;
    for (i = 0; i < n; ++i)
    {
        for (j = 0; j < n; ++j)
        {
            printf("%4d",arr[j][i]);
        }
        printf("\n");
    }
}

8 兔子生崽问题(4分)

题目内容:

假设一对小兔的成熟期是一个月,即一个月可长成成兔,那么如果每对成兔每个月都可以生一对小兔,一对新生的小兔从第二个月起就开始生兔子,试问从一对兔子开始繁殖,n(n<=12)月以后可有多少对兔子(即当年第n月份总计有多少对兔子,含成兔和小兔)?请编程求解该问题,n的值要求从键盘输入。

参考答案:依题意,兔子的繁殖情况如图所示。图中实线表示成兔仍是成兔或者小兔长成成兔;虚线表示成兔生小兔。观察分析此图可发现如下规律:

(1)每月小兔对数 = 上个月成兔对数。

(2)每月成兔对数 = 上个月成兔对数 + 上个月小兔对数。

综合(1)和(2)有:每月成兔对数 = 前两个月成兔对数之和。

用fn(n=1,2,…)表示第n个月成兔对数,于是可将上述规律表示为如下递推公式:

int f(int n);

int main() 
{
    int n;
    printf("Input n(n<=12):\n");
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) 
    {
        printf("%4d", f(i));
    }
    printf("\nTotal=%d\n", f(n));
    return 0;
}

int f(int n)
{
    if(n == 1)
    {
        return 1;
    }
    else if(n == 2)
    {
        return 2;
    }
    return f(n -1) + f(n - 2);
}

9 抓交通肇事犯(4分)

题目内容:

一辆卡车违犯交通规则,撞人后逃跑。现场有三人目击事件,但都没记住车号,只记下车号的一些特征。甲说:牌照的前两位数字是相同的;乙说:牌照的后两位数字是相同的,但与前两位不同;丙是位数学家,他说:四位的车号刚好是一个整数的平方。现在请根据以上线索帮助警方找出车号以便尽快破案。

[提示]:假设这个4位数的前两位数字都是i,后两位数字都是j,则这个可能的4位数

k = 1000*i + 100*i + 10*j + j

式中,i和j都在0~9变化。此外,还应使k=m*m,m是整数。由于k是一个4位数,所以m值不可能小于31。

int main()
{
    int k, m;
    for (m = 31; m <= 99; ++m)
    {
        k = m * m;
        if(k / 1000 == k % 1000 / 100 && k % 100 / 10 == k % 10 && k % 100 != (k / 1000) * 10 + k % 1000 / 100)
        {
            printf("k=%d,m=%d\n", k, m);
        }
    }
    return 0;
}

10 检验并打印幻方矩阵(4分)

题目内容:

幻方矩阵是指该矩阵中每一行、每一列、每一对角线上的元素之和都是相等的。从键盘输入一个5×5的矩阵并将其存入一个二维整型数组中,检验其是否为幻方矩阵,并将其按指定格式显示到屏幕上。

#define N 5

int Check(int arr[N][N], int n);

int main() 
{
    int arr[N][N];
    //获取输入
    for (int i = 0; i < N; ++i)
    {
        for (int j = 0; j < N; ++j)
        {
            scanf("%d", &arr[i][j]);
        }
        getchar();
    }
    if(Check(arr,N))
    {
        printf("It is a magic square!\n");
        for (int i = 0; i < N; ++i)
        {
            for (int j = 0; j < N; ++j)
            {
                printf("%4d", arr[i][j]);
            }
            printf("\n");
        }
    }
    else
    {
        printf("It is not a magic square!\n");
    }

    return 0;
}

int Check(int arr[N][N], int n)
{
    int i, j, sum, s1, s2, s3, s4, flag = 1;
    for (i = 0; i < n; ++i)
    {
        s1 = s2 = s3 = s4 = 0;
        for (j = 0; j < n; ++j)
        {
            //行合
            s1 += arr[i][j];
            //列合
            s2 += arr[j][i];

            //对角    00,11,22,33,44
            s3 += arr[j][j];
            //       04,13,22,31,40
            s4 += arr[j][N - j - 1];

        }
        //将第一行的合保存
        if(i == 0)
        {
            sum = s1;
        }
        //有一个不相等就退出
        if(s1 != sum || s2 != sum || s3 != sum || s4 != sum)
        {
           flag = 0;
           break;
        }
    }
    return flag;
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值