C专题上机问题总结

Sex1-递归

1.部分同学针对于递归函数的理解不够深刻。可参考以下链接加以巩固复习。https://www.zhihu.com/question/31412436/answer/683820765?utm_source=wechat_session&utm_medium=social&utm_oi=931879418771615744
2.“6-5 递归实现顺序输出整数”。该题需顺序输出整数,而针对整数取余操作是按照从低位到高位的顺序,因此在递归过程中,需要先调用printdigits()函数,再printf()实现从高位到低位的输出。注意输出整数的输出顺序,需考虑个别样例(例如n为100000,0,1等)。
3.“6-6 判断满足条件的三位数”。该题可以在递归过程中从n开始依次递减直到100结束,判断区间内每个数是否符合题目要求。判断一个三位数n是否有两位重复,可以构建一个长度为10的数组arr,分别截取n对位个位、十位、百位并通过数组记录其数字是否重复(如arr[i]>=2则说明i在n中出现了两次)。
另:如有不明白的知识点或题目,请大家一定要及时和我沟通。

Sex1p-递归续

1 正整数拆分

本题目难度在于正整数拆分过程的输出。大部分同学都尝试了在拆分的过程中直接输出整数n,试想是否可以换成一种思路:用一个数组记录每次拆分的结果,在拆分过程中不需考虑输出,在单次拆分结束后统一输出。例如:

10=4+3+2+1  先用数组记录每次拆分的结果:array=[4,3,2,1]
10=1+1+1+1+1+1+1+1+1+1  每次拆分的结果:array=[1,1,1,1,1,1,1,1,1,1]

因此,问题就可以转换为如下两部分:

  1. 递归求取正整数拆分的数组表示。
  2. 对于每次求取的数组,进行格式化输出。

正向考虑正整数n的拆分有些困难,可以逆向思考:
假设不考虑n的大小,我们可以列举实现数组array=[n-1,n-1,…n-1,n-1,n-1]、[1,1,1,…,1,1,1]对应所有元素的和sum,判断sumn的大小即可,大小关系分为以下三种情况:

  1. sum>n:数组之和大于该正整数,例如n=6,且array=[3,2,2],说明该样例不符,直接退出。
  2. sum==n:数组之和等于该正整数,例如n=6,且array=[3,2,1],说明该样例符合,需要进行格式化输出。
  3. sum<n:数组之和小于该正整数,例如n=6,且array=[3,2],说明该样例数据较少,需要进行进一步递归增加样例。

针对以上分析,array和n可以设置为全局变量,确定递归函数divisionInteger()参数有以下几个:

  • array_len: 当前已经拆分的整数的个数,即当前记录的已经划分的数量
  • sum: 当前已经划分整数的总和
  • next_max_value: 根据样例输出可以看出,其划分的每项整数均不大于其前面一项(单调递减),因此需要一个参数记录并确定下一次递归时数组的最大值,该最大值不超过数组的最大值。

整理得,伪代码大致可以如下:

variable array[ARRAY_LENGTH];
integer n;
void divisionInteger(array_len, sum, next_max_value)
{
	if sum>n:
		return
	else if  sum==n:
		格式化输出n及数组
	else:
		for i in range(next_max_value, 1):
			array[array_len] = i		//记录第array_len个数为i
			divisionInteger(array_len+1, sum+i, i)	//由于array添加了一个数,因此sum也需要加上,由于该数组是单调递减的,因此下一个数值需要限定为不大于i
}

针对以上代码, 可以进一步尝试剪枝,不详细介绍,同学们可以自行尝试。

PS:
本题仅要求输出正整数拆分,递归求整数划分个数也是比较有意思的方向,感兴趣的同学可以递推公式实现求整数划分个数。

2 求迷宫最短通道

参考思路:
本题利用深度优先遍历(DFS),寻找到能到达终点的所有可能路径对应的长度。然后记录最短路径并输出。
迷宫问题每走一步都有四种选择(上右下左),先选择一个方向,如果该方向能够走下去,那么就往这个方向走,当前位置切换为下一个位置,步长+1。如果不能走,则换个方向,如果所有方向都走不了,那么退出当前位置,到上一步的位置去,当前位置切换为上一步的位置,步长-1。一直这样执行下去,要么可以找到终点,要么所有的路径都没能到达终点。值得注意的是,为了求取最短路径,可以在终点时比较步长信息,取最短步长即可。

除此之外,广度优先遍历能够实现直接求取最短路径,可以自行探索。

专题课-模块化程序设计

本专题考察以下知识点:

  1. “完成M1要做的内务工作,即发送一条消息在屏幕上"Hello M2, I am M1\n" , 然后检查 M2 的任务是否完成”:因此,M1Task()的任务包括两部分:第一为完成对应的内务工作,第二为检查M2是否完成。
  2. “虚拟组员M1的内务工作别人是看不到的”:为保证其他模块无法调用对应的内务工作,需要将模块的内务工作单独列出为一个函数A(),可利用某关键词将该函数A()限定为仅能在该模块内访问。为使外部能够调用该模块的任务函数M1Task(),需要将该函数暴露出去。
  3. M*Task()函数,可以自行设定参数及返回值类型。
  4. 该系统限定文件写入模式为"w+",在管理员模式下输出到屏幕的签到信息,可以不必从文件中读取。

SEx3p-指针进阶续

2-5 定义带参数的宏“#define JH(a,b,t) t = a; a = b; b = t”,对两个参数a、b的值进行交换,下列表述中正确的是()。

  • A. 不定义参数a和b将导致编译错误
  • B. 不定义参数a、b、t将导致编译错误
    解析:编译器不会检查宏参有没有定义,因此无论是否定义a、b、t都不导致编译错误
  • C. 不定义参数t将导致运行错误
    解析:无论是否定义a、b、t都不导致编译错误。但是,不定义参数t将导致运行错误,因为交换两个数值需要一个变量来过度
  • D. 不需要定义参数a、b、t类型
  • 解析:宏里的参数不是变量,只是简单的替换,不需要定义类型。但是宏参只是达到替换的作用,不能定义它的类型,如果不定义,虽然不会导致编译错误,但是会出现运行错误

2-7 下面说法中正确的()

  • A. 若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度
    解析:变量分为全局变量和局部变量。局部变量和形参的作用域是函数内部,全局变量的作用域是整个文件。但可以通过声明一个extern的全局变量拓展全局变量的作用域,也可以通过定义一个static的全局变量限制这种拓展。
  • B. 若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度
    解析:如果全局变量仅仅由单个函数访问,不存在耦合度的问题
  • C. 设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑变量生命周期问题
    解析:动态全局变量、静态全局变量、静态局部变量的生命周期都为程序运行期间,其中静态局部变量的生存周期虽然为整个源程序,但是其作用域仍然与局部变量相同,当退出函数是,该变量还存在,但是不能使用。
  • D. 静态全局变量使用过多,可那会导致动态存储区(堆栈)溢出
    解析:局变量和静态变量都是存储在静态存储区,所以在递归调用是不会压栈,也不会造成堆栈溢出。

SEx4p - 指针续

  • 6-1 用单向链表完成多项式运算”。本题考察链表的增删改查。注意输出格式需符合书写格式,建议如下的输出格式:。
系数指数是否首项输出格式
---正常输出
0--省略输出
1或-11省略系数及指数:+x^1或-x^1–>+x或-x
1或-11省略系数、指数及前置加号:+x^1或-x^1–>x或-x
正数k1省略前置加号:+kx^1–>kx
正数k0省略x: +kx^0–>+k
正数k0省略x及前置加号:+k–>k
负数k0-省略x: kx^0–>k

另外,测试不通过时,建议尝试以下几种情况:

  • 两多项式的指数都不相同,包括指数为0
  • 常数(包括0)与1个多项式
  • 一个多项式与一个常数(包括0)
  • 两多项式的指数都为正数
  • 两多项式的指数有正负不一样或一样
  • 两多项式的项数不同,指数有正负不一样或一样
  • 两多项式的项数和系数任意
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值