CSU计算机学院2023秋C语言期中题目思路分享(前三道题)

文章目录

  • 写在前面
  • A:个税计算——阅读理解与数据类型转换
    • 原题
        • 输入
        • 输出
        • 样例输入
        • 样例输出
    • 题目分析
      • 题目理解
      • 代码实现与问题解决
    • 我的代码
  • B:时制转换——问题是一点点解决的
    • 原题
        • 输入
        • 输出
        • 样例输入
        • 样例输出
    • 题目分析
    • 我的代码
  • C:统计进位——人教版小学二年级数学上册第二单元《进位加》的C语言实现
    • 原题
        • 输入
        • 输出
        • 样例输入
        • 样例输出
    • 题目分析
      • 数据读入与存储
      • 准备列竖式吧!
      • 竖式的加法计算
    • 我的代码

写在前面

题目:中南大学计算机学院2023秋季C语言期中考考题(共六道,本文分享前三道的思路)
旨在分享自己的思考过程和一点经验,并给出一种输出正确的答案供大家讨论批判,有任何批评、问题可以直接在评论区留言或者直接私信告诉我,大家共同进步。
文字主要面向新手

A:个税计算——阅读理解与数据类型转换

原题

小南毕业工作了,他想知道自己每年的扣税情况。他查到的综合所得的个人所得税税率表如下:

级数全年应纳税所得额税率(%)速算扣除数
1不超过36000元的部分30
2超过36000-144000元的部分102520
3超过144000-300000元的部分2016920
4超过300000-420000元的部分2531920
5超过420000-660000元的部分3052920
6超过660000-960000元的部分3585920
7超过960000元的部分45181920

你能根据小南的收入算出他每年所要缴纳的税款吗?

输入

多个样例。每个样例输入一个整数m(104≤m≤107)代表小南的年终收入,为100的整数倍。

输出

每个样例输出一个整数,表示小南缴纳的个税。每个样例输出结果占一行。

样例输入
20000
36000
400000
660000
样例输出
600
1080
68080
145080

题目分析

这题有同学拿到手,没听过速算扣除数,不知怎么算。有同学知道了怎么算,提交只有80%,我们来看看。

题目理解

其实速算扣除数不论有没听过,怎么看都是要减去这个数的,怎么减?乘以税率之前还是之后?还有超过“的部分”,是不是要单独每部分算?其实这些问题全可以靠样例来解决——当题目关于计算方法、计算公式等没有用详尽的文字表述时,不需要太纠结,从样例输入输出可以判断出计算方法。

比如这题,大可以猜一猜怎么算,第一组第二组明显是20000×0.03,36000×0.03,没有问题。第三组400000,先别想太多,400000×0.25是100000,而结果是68080,也该看出来了,是100000减去对应的速算扣除数。

现在明白了,就是简单的乘以税率减去扣除数,带入第四组按一下计算器,没有问题。

代码实现与问题解决

大致涉及到这些知识:

  • 区间数if语句判断
  • 精度问题和解决
    我们一个个看
  1. if语句判断区间
    这时候有一种思想,按顺序判断,承上启下结构。什么意思呢?先判断是否大于A,else if是否大于B,此时由于else if只会在前一个if语句为假的时候判断,所以当判断这个“是否大于B”,就隐含了“不是大于A”的前提,也就是大于B,并且小于等于A。简单的思想,自己写过一次就能知道了。
    好处就是不用再写 大于B&&小于等于A了,结构也清晰。
    具体代码就是长这样:

    if(n > 960000){t = n * 0.45 - 181920;
    }else if(n > 660000){t = n * 0.35 - 85920;
    }else if(n > 420000){t = n * 0.30 - 52920;
    }else if(n > 300000){t = n * 0.25 - 31920;
    }else if(n > 144000){t = n * 0.20 - 16920;
    }else if(n > 36000){t = n * 0.10 - 2520;
    }else{t = n * 0.03;
    }
  2. 精度问题和解决
    有同学看到百分比,下意识用了小数处理,这就要注意精度问题了。例如这样写,就会遇到错误80%,有的数算出差1:

#include <stdio.h>
int main(){int n;while(scanf("%d", &n) != EOF){int t;if(n > 960000){t = n * 0.45 - 181920;}else if(n > 660000){t = n * 0.35 - 85920;}else if(n > 420000){t = n * 0.30 - 52920;}else if(n > 300000){t = n * 0.25 - 31920;}else if(n > 144000){t = n * 0.20 - 16920;}else if(n > 36000){t = n * 0.10 - 2520;}else{t = n * 0.03;}printf("%d\n", t);}return 0;
}

这是因为在整数、小数之间转换的时候,会丢失精度,此时可以把t声明成float,输出使用%.0f既可。

当然,脑子转的快的同学看到题目中的“100的整数倍”,下意识的除以100,这是最好的,也就是在积算的时候先除以100,此时得到的一定是精确的整数,再乘以百分比,这样就不会损失精度了。

我的代码

#include <stdio.h>
int main(){int n;while(scanf("%d", &n) != EOF){float t;if(n > 960000){t = n * 0.45 - 181920;}else if(n > 660000){t = n * 0.35 - 85920;}else if(n > 420000){t = n * 0.30 - 52920;}else if(n > 300000){t = n * 0.25 - 31920;}else if(n > 144000){t = n * 0.20 - 16920;}else if(n > 36000){t = n * 0.10 - 2520;}else{t = n * 0.03;}printf("%.0f\n", t);}return 0;
}

或者:

#include <stdio.h>
int main(){int n;while(scanf("%d", &n) != EOF){int t;if(n > 960000){t = n / 100 * 45 - 181920;}else if(n > 660000){t = n / 100 * 35 - 85920;}else if(n > 420000){t = n / 100 * 30 - 52920;}else if(n > 300000){t = n / 100 * 25 - 31920;}else if(n > 144000){t = n / 100 * 20 - 16920;}else if(n > 36000){t = n / 100 * 10 - 2520;}else{t = n / 100 * 3;}printf("%d\n", t);}return 0;
}

B:时制转换——问题是一点点解决的

原题

12小时制和24小时制都是一种记录时间的方式,两者的区别在于:

(1)12小时制是把一天二十四小时分为上午和下午两个十二小时的时间段,上午从午夜12:00到上午11:59,后缀标记am或者AM,下午从正午12:00到晚上11:59,后缀标记pm或者PM。

(2)24小时制是把一天二十四个小时从午夜开始用00:00~23:59表示。

(3)使用12小时制显示时间时中午12点显示为12:00 pm或者12:00 PM,而将午夜显示为12:00 am或者12:00 AM。

小南的任务:将12小时制格式显示的时间转换为24小时制格式显示。

输入

多个样例。每个样例输入1行形式为hh:mmcd的数据,其中整数hh(00≤hh≤12)代表小时,整数mm(00≤mm≤59)代表分钟,cd是字母组合“am、AM、pm、PM”中的一个,分别表示上午(am或AM)和下午(pm或者PM)。

输出

每个样例输出新的24小时制格式的时间,形式为hh:mm。每个样例输出结果占一行。

样例输入
12:00am
12:59PM
11:09pm
03:02AM
04:18PM
样例输出
00:00
12:59
23:09
03:02
16:18

题目分析

拿到这个题目,大概脑子里会有两个问题:怎么读入数据?怎么转换?我们一个个看。

我们先读入数据:整数+冒号+整数+一个字符+一个字符。怎么读?%d:%d%c%c这样就行了!C语言先识别一个整数,遇到非数字后停止(这里是遇到了“:”,它发现这个不是数字,又把它放回去了),然后找一个冒号,再找一个整数,同理遇到p、P、a、A后停止。最后读两个字符。

这样分别存到四个变量后,就可以开始核心部分了。

怎么转换?转换就是把不同的东西变成相同的,什么不同?12小时和24小时最大的不同就在下午,也就是中午12点过后(pm),下午4点就是16点,下午9点就是21点——明显是+12。

这下明白了:只要pm(或者PM),把小时数加12就行了。

于是乎写出代码:

#include <stdio.h>
int main(){char a, b;int h, m;while(scanf("%d:%d%c%c", &h, &m, &a, &b) != EOF){if(a == 'p' || a == 'P'){h += 12;}printf("%02d:%02d\n", h, m);}return 0;
}

但是看看样例就知道出了问题:

  1. 12:00am应当是00:00,怎么办?好说,如果小时数是12,而且是am,那就变成0——除此之外,am都和24小时的小时数是一样的,比如早上3点就是3:00,这是一致的,除了12:00am。
  2. 12:00pm应当是12:00,怎么办?好说,当是pm,小时数不是12的时候,再加12就行了。
    我们说问题是一点点解决的,虽然这个问题脑子转得快的同学第一次看题就能看出来,但是如果一次想不到也没有关系,通过一步步修改、调试来完善代码,最后也能达到正确答案,这正是遇到复杂问题的解决方法。当然在不断的训练中也要有意识的想一想:漏了什么?想全了吗?有没有别的情况?尽量在测试之前自己找出一些问题,或者尽量提前预料到问题,提前规避。比如这一题,在题目中强调了12点的问题,是应当加以留意的。

我的代码

#include <stdio.h>
int main(){char a, b; // 存储pm、amint h, m; // 存储小时、分钟(分钟是没有用的)while(scanf("%d:%d%c%c", &h, &m, &a, &b) != EOF){ // 读入数据if((a == 'a' || a == 'A') && h == 12){ // 如果是am,并且小时数是12的话,小时数转成0h = 0;}if((a == 'p' || a == 'P') && h != 12){ // 如果是pm,而且小时数不是12的话,小时数加12h += 12;}printf("%02d:%02d\n", h, m); // 输出,%02d是用0来补位到两位}return 0;
}

C:统计进位——人教版小学二年级数学上册第二单元《进位加》的C语言实现

原题

老师发现很多学生在进行加法的时候,发现“进位”特别容易出错。于是交给小南一个任务,就是统计两个整数x和y在相加时需要多少次进位,其中x和y满足0≤x,y≤ 109,你能帮他完成任务吗?

输入

多个样例。 每个样例输入1行,包括2个整数x和y(0≤x,y≤ 109)。

输出

每个样例输出一个整数,代表所需要的进位数。每个样例输出结果占一行。

样例输入
8 7
9 0
154 246
555 5555
123 594
样例输出
1
0
2
3
1

题目分析

先来看看进位是什么:根据人教版小学二年级数学上册第二单元《进位加》知识可得,加法列竖式的时候,每一位相加(上一位有进位的还要加上上一位的进位1)大于10就是进一次位,以此类推。

例如9234+928:(从右看到左)
在这里插入图片描述

注意两点:

  • 后一次相加要加上前一次的进位1(如果前一次有进位),前一次没有进位可以看作加上0
  • 最后一位位数不足,可以补上0思考,比如上述例子928可以看作0928

很简单对吧!我的思路就是把列竖式的过程完完整整地搬到代码中。来看看吧!

数据读入与存储

首先想到的是需求,我要把两个数字右对齐“列竖式”,然后一位一位加。此时想想用int变量存储可以吗?当然可以,但是有点麻烦——每一位的提取很麻烦!看看这些对齐的数像什么?其实实质上就是一个二维数组,当然这里只有两行(只有两个数相加),用两个长度相同的数组也是可以滴。

此时用两个数组存储两个数的每一位就是第一步。当然可以用int数组,也可以用字符串数组,根据输入,用字符串显然方便一点:scanf("%s %s", a, b)就行了!

至于字符怎么转数字,也是一个经典用法,教材中也有提到:C语言的字符是用整型存储的,'0'就是48(在ASCII码下),'1'也就是49了,自然,用数字的字符减去'0',就是这个数的int型了!这样我们得到了两个数组,它们是这样的:

准备列竖式吧!

显然,这些数的长度不尽相同,默认读入的顺序明显是左对齐,这时候按照小学二年级的知识,我们要对它们进行右对齐:
在这里插入图片描述

明确一下数组的长度,题目要10位,保险起见设为100位吧!(doge)就可以写代码了(代码的功能就是上图的转换,应该是能明白的):

// 这里a1数组是a数组转换(右对齐)后的数组,b1同理
for (int i = 0; i < alen; i++) { // alen是用strlen函数获取的a数组的实际长度(也就是数字的长度,例如9234长度是4)a1[99 - i] = a[alen - i - 1];
}
for (int i = 0; i < blen; i++) {b1[99 - i] = b[blen - i - 1];
}

这种代码的核心就是带数字,往里带入几位试一试,就可以推出应该写什么了。比如a1的最后一位应该等于a的第4位,倒数第二位应该等于a的第3位,也就是a1[99] = a[3]a1[98] = a[2](注意数组的索引从0开始)。然后带入a、b的数组长度和变量i(i是从零开始增长的):a[99 - i] = a[alen - 1 - 1],数组的索引就是这样代入出来的。

好了,可以开始相加了。思考列竖式的过程,明确一下需要哪些变量:

  • 存储两数再加进位1(如果有的话)的变量k(就是判断k是否大于等于10的)。
  • 进位c,第一次加法c = 0,如果k大于等于0,c赋值为1,否则赋值为0,下一次算k的时候加上c就行了。

想一想,竖式从右到左的加法用什么实现?明显是for循环,循环多少次呢?观察列竖式的过程,不难看出,4位加3位,总共加了4次(包括最后一位加进位1)。想一想,4位加4位,总共加了4次;4位加10位,总共加了5次。——规律很清晰,如果两数位数相等,那就是循环次数就是两数位数;如果不相等,就是最短位数+1。

当然,你可以直接把所有列表中所有数字都循环遍历一遍,等等,是不是想到什么问题?——早该想到的!前面两个数不一样长的时候就该想到了——要保证数组中除了输入的数字外,其他都是'0'!这就需要在最开始时初始化a1、b1两个数组。这样就能保证不漏、不多,因为0+0不可能使得进位次数增多。

初始化是这样的:

for (int i = 0; i < 100; i++){a1[i] = '0';
}for (int i = 0; i < 100; i++){b1[i] = '0';
}

为什么不能char a1[100] = {'0'}?答案是这样只会把第一项令为'0',但是其余项会令成ASCII码为0的空字符'\0',这不是我们想要的。此时用循环才是保险。

竖式的加法计算

现在列好了竖式,开始计算吧!原理在上面陈述的很明白了,代码是这样的:

int k, c = 0, s = 0;                   // k、c上面说过了,s是存储进位次数的,也就是题目要输出的答案
for (int i = 99; i >= 0; i--) {        // 从最后一位开始循环,遍历整个列表(懒了,不想做判断了)k = a1[i] - '0' + b1[i] - '0' + c; // 计算k值,注意最后加上进位c,第一次计算的时候进位c为0if (k >= 10) {                     // 如果算出来大于等于10s++;                           // 统计进位次数+1c = 1;                         // 进位1} else {                           // 如果算出来在10以内c = 0;                         // 进位0}
}

结束了!我本题的思路就是模拟列竖式的方式进行计算。考试的时候中间犯了几次错误:

  • 转换右对齐的时候没整明白,把顺序颠倒了,9234对齐到右边变成4329了
  • 没有初始化a1、b1,导致错误
    当然遇到错误,先不要慌张,通过分段调试代码、找出原因、修改,都是可以解决的,问题是一点点解决的嘛。

我的代码

#include <stdio.h>
#include <string.h>
int main()
{char a[100], b[100], a1[100], b1[100];while (scanf("%s %s", a, b) != EOF) {for (int i = 0; i < 100; i++) {a1[i] = '0';}for (int i = 0; i < 100; i++) {b1[i] = '0';}int alen = strlen(a);  // 注意使用strlen要#include <string.h>int blen = strlen(b);// 这里a1数组是a数组转换(右对齐)后的数组,b1同理for (int i = 0; i < alen; i++) { // alen是用strlen函数获取的a数组的实际长度(也就是数字的长度,例如9234长度是4)a1[99 - i] = a[alen - i - 1];}for (int i = 0; i < blen; i++) {b1[99 - i] = b[blen - i - 1];}// 分位次加法int k, c = 0, s = 0;                   // k、c上面说过了,s是存储进位次数的,也就是题目要输出的答案for (int i = 99; i >= 0; i--) {        // 从最后一位开始循环,遍历整个列表(懒了,不想做判断了)k = a1[i] - '0' + b1[i] - '0' + c; // 计算k值,注意最后加上进位c,第一次计算的时候进位c为0if (k >= 10) {                     // 如果算出来大于等于10s++;                           // 统计进位次数+1c = 1;                         // 进位1} else {                           // 如果算出来在10以内c = 0;                         // 进位0}}printf("%d\n", s);}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/202275.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

编程语言分类

如果要将编程语言分成两大类&#xff0c;可以考虑以下分类方式&#xff1a; 编译型语言&#xff08;Compiled Languages&#xff09;&#xff1a;这类语言在运行之前需要通过编译器将源代码转换为机器码或类似形式的可执行代码。编译型语言的特点包括&#xff1a; 需要显式的编…

用PHP与html做一个简单的登录页面

用PHP与html做一个简单的登录页面 login.html的设计 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title&…

我一人全干!之二,vue3后台管理系统树形目录的实现。

一个完整的后台管理系统需要一个树形结构的目录&#xff0c;方便用户切换页面。 因为使用的是element-plus的ui库&#xff0c;所以首选el-menu组件&#xff0c;点击查看文档。 因为此组件不是树形结构的&#xff0c;所以需要封装成系统需要的树形结构组件。可以使用vue的递归组…

Vue3 Element-Plus 一站式生成动态表单:简化前端开发流程

文章目录 1. 引言2. Vue3 和 Element-Plus 简介2.1 Vue32.2 Element-Plus 3. 动态表单的需求与挑战4. Vue3 和 Element-Plus 动态表单的优势4.1 Vue3的组合式API4.2 Element-Plus的表单组件 5. 一站式生成动态表单的实现5.1 准备工作5.2 创建动态表单组件5.3 使用动态表单组件 …

2023年2月8日 Go生态洞察:Profile-Guided Optimization预览

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

易点易动设备管理系统--提升设备能耗管理效率的工具

在当今的节能环保意识日益增强的社会背景下&#xff0c;设备能耗管理成为了市场推广人员关注的焦点之一。为了帮助市场推广人员提升设备能耗管理效率&#xff0c;易点易动设备管理系统应运而生。本文将详细介绍易点易动设备管理系统的功能和优势&#xff0c;以及如何借助该系统…

2023年12月实时获取地图边界数据方法,省市区县街道多级联动【附实时geoJson数据下载】

首先&#xff0c;来看下效果图 在线体验地址&#xff1a;https://geojson.hxkj.vip&#xff0c;并提供实时geoJson数据文件下载 可下载的数据包含省级geojson行政边界数据、市级geojson行政边界数据、区/县级geojson行政边界数据、省市区县街道行政编码四级联动数据&#xff0…

音视频之旅 - 基础知识

图像基础知识 像素 像素是图像的基本单元&#xff0c;一个个像素就组成了图像。你可以认为像素就是图像中的一个点。在下面这张图中&#xff0c;你可以看到一个个方块&#xff0c;这些方块就是像素 分辨率 图像&#xff08;或视频&#xff09;的分辨率是指图像的大小或尺寸。…

简单桶排序

#include<stdio.h> int main() { int a[11], i, j, t; for (i 0;i < 10;i) a[i] 0;//初始化为零 for (int i 1;i < 5;i)//循环输入5个数&#xff1b; { scanf("%d", &t);//把每一数读取到变量t中 a[t];/…

阿里云上传文件出现的问题解决(跨域设置)

跨域设置引起的问题 起因&#xff1a;开通对象存储服务后&#xff0c;上传文件限制在5M 大小&#xff0c;无法上传大文件。 1.查看报错信息 2.分析阿里云服务端响应内容 <?xml version"1.0" encoding"UTF-8"?> <Error><Code>Invali…

Excel VBA应用技巧

文章目录 第一章 Range &#xff08;单元格&#xff09;对象1. 单元格的引用方法1.1 使用Range 属性1.2 使用Cells 属性1.3 使用快捷记号1.4 使用Offset 属性1.5 使用Resizae 属性1.6 使用Union 方法1.7 使用UsedRange 属性1.8 使用CurrentRegion 属性 2. 选定单元格区域的方法…

NX二次开发自制UI界面大小设置

1、进入NX&#xff0c;点击“应用模块->更多->块UI样式编辑器”&#xff0c;进入UI编辑界面&#xff1b; 2、设置“Dialog->其他->DialogSizing”为Allow Resize 3、添加滚动窗口控件&#xff0c;设置Width、Height的值即可改变UI界面大小&#xff0c;注意&#x…

异常捕获后,如果事务回滚了,后面对数据库的操作需要加事务,不然对数据库的修改不会生效

异常捕获后&#xff0c;如果事务回滚了&#xff0c;后面对数据库的操作需要加事务&#xff0c;不然对数据库的修改不会生效

service层报错:Invalid bound statement (not found)

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一份大厂面试资料《史上最全大厂面试题》&#xff0c;Springboot、微服务、算法、数据结构、Zookeeper、Mybatis、Dubbo、linux、Kafka、Elasticsearch、数据库等等 …

2023中医药国际传承传播大会暨中医药图片和非遗艺术展隆重揭幕

由世界针灸学会联合会、中新社国际传播集团、中国新闻图片网、中国民族医药学会、中国针灸学会联合主办的“2023中医药国际传承传播大会”3日在广东省深圳市举办&#xff0c;“中医药国际传承传播图片展”与“非遗艺术展”在大会举办期间开展迎客。会议聚焦非遗健康、非遗传承等…

MySQL生成UUID并去除-

uuid()函数 uuid() 函数可以使mysql生成uuid,但是uuid中存在-,如下图&#xff1a; 去除uuid的- 默认生成的uuid含有-&#xff0c;我们可以使用replace函数替换掉-&#xff0c;SQL如下 select replace(uuid(),"-","") as uuid;Insert语句中使用UUID 如果…

JAVA全栈开发 day18MySql03

一、复习 为什么要用数据库数据库好处数据库的发展史​ 层次模型​ 网状模型​ 关系模型&#xff08;二维表专门存储数据&#xff0c; 表与表的关联&#xff09;​ 表与表的关系&#xff1a; 1对1 &#xff0c;1对多&#xff0c;多对多​ 非关系模型关系模…

【ArcGIS Pro微课1000例】0051:创建数据最小几何边界范围(点、线、面数据均可)

本实例为专栏系统文章:创建点数据最小几何边界(范围),配套案例数据,持续同步更新! 文章目录 一、工具介绍二、实战演练三、注意事项一、工具介绍 创建包含若干面的要素类,用以表示封闭单个输入要素或成组的输入要素指定的最小边界几何。 工具界面及参数如下所示: 核心…

什么是高防IP,高防IP该如何选择。

高防IP&#xff0c;指的是高防御能力的IP地址。在互联网的世界里&#xff0c;网络安全问题成为一个重要的话题。作为一个用户&#xff0c;你是否曾遇到过被黑客攻击造成的网站瘫痪、信息泄露等问题&#xff1f;如果你是一个企业&#xff0c;你是否考虑过自己公司的网站和业务的…

大模型在企业知识库场景的落地思考

一、引言 在这个信息爆炸的时代&#xff0c;企业的知识库已不再是简单的数据堆砌&#xff0c;而是需要智能化、高效率的知识管理和利用。大模型作为AI领域的一个重要突破&#xff0c;正逐步成为企业知识库管理的强大助力。通过前面一段时间对于大模型在企业落地的深入调研和实…