![](https://img-blog.csdnimg.cn/20201014180756923.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
《编程思维与实践》
文章平均质量分 52
收纳oj上的练习题和部分自主练习题
snow-clad
摸鱼的大学牲
展开
-
《编程思维与实践》1092.显示路径
注意到xy±20±21...±2n为奇数,所以一个点能到达的必要条件为|x|+|y|是奇数.特别地,我们称|x|+|y|为一个点和原点间的曼哈顿距离.观察到:①走一步时有∣x∣∣y∣1∈021;②走两步时有∣x∣∣y∣∈022可能取值为1和3其中新增的3∈2122;③走三步时有∣x∣∣y∣∈023可能取值为135和7其中新增的5和7∈2223;④走四步时有∣。原创 2023-05-16 21:25:19 · 95 阅读 · 0 评论 -
《编程思维与实践》1082.波兰表达式
法一(递归):因为操作是对最近的两个数据进行,所以符合递推规律.由于每组字符串之间都由空格分割,所以可以通过scanf读入,同时注意到每一行结束必然会得到结果 所以不用担心会读入下一行的内容.法二(栈模拟):先将读入的字符串全部储存起来,再逆向遍历,遇到数据就入栈,遇到符号就取出栈中的两个元素运算完再入栈,最终结果就是栈中的最后元素.原创 2023-05-15 20:42:16 · 68 阅读 · 0 评论 -
《编程思维与实践》1094.坏掉的彩灯
注意到RBYG四个字母必然会以某种顺序相同地不断出现:如:RYBGRYBGR可以视为RYBG不断出现,也可以理解为YBGR不断出现( RYBGRYBGR ),所以只需要找到连续四个出现的字母即可.具体操作:开一个数组cnt记录连续四个出现字母的先后顺序,同时用一个数组num存RBYG四个字母出现的个数,再用另一个数组temp存理论上应该出现的字母个数.以!RGYB 为例:cnt存的内容为 1,2,3,0 表明以BRGY顺序不断出现,原创 2023-05-16 19:30:15 · 59 阅读 · 0 评论 -
《编程思维与实践》1096.移动游戏
如上图所示,要满足a−xmx0和b−ymy0,只有a和b均可在同一轮次到达,即可求得共同的m时,才满足条件.需要注意的是,如果a−x0且x00则在任意轮次均可到达.注意的点:判断a−x和x0时应该先判断0的情况,避免除以0 .原创 2023-05-16 20:19:30 · 47 阅读 · 0 评论 -
《编程思维与实践》1065.浮点数减法
处理方法与浮点数加法基本一致,但为了方便减法符号的判定,这里采用模仿大整数的处理方法将浮点数定义为结构体,其中cnt存整数的位数,sign记录符号,但浮点数为顺序存储;减法复用Big Integer的代码即可,需要注意的是比较的是整数位数,如果相等需要比对每一位(包括小数位).注意的点:1.进位是从最低位开始进位,如果是顺序存储需要从末尾开始遍历;2.整数部分为0需要特殊处理,去除前置0时也要记得保留整数最后一位.原创 2023-05-12 15:48:32 · 141 阅读 · 0 评论 -
《编程思维与实践》1054.负二进制
结合负基数进制和大整数除法求余操作的思路即可.由于涉及符号,所以要补充参数记录符号,格外注意在复用二进制倒置的代码时需要注意符号:进行除法时我们都用绝对值进行运算,余数的符号由被除数决定,商的符号由被除数和除数决定.原创 2023-05-14 17:31:53 · 98 阅读 · 0 评论 -
《编程思维与实践》1071.猜猜猜
对于首字符而言,如果后一位字符与之相同,则首位选法只有1种,不同则2种;对于最后一位字符而言,如果前一位字符与之相同,则末位选法只有1种,不同则2种;对于中间的字符而言,有以下几种可能:1.中间字符与前后字符均不同且前后字符不同(abc型):则中间字符有3种选法;2.中间字符与前后字符均不同且前后字符相同(aba型):则中间字符有2种选法;3.中间字符与前后某一个字符相同(aac型),则中间字符有2种选法;4.中间字符与前后两字符都相同(aaa型),则中间字符有1种选法.原创 2023-05-14 13:50:08 · 190 阅读 · 0 评论 -
《编程思维与实践》1091.优雅的括号序列
法一:通过栈直接进行模拟: 左括号入栈 , 右括号出栈.入栈前提: 栈空或者栈非空但满足小中大括号的内外次序;出栈前提: 栈非空且满足小中大括号的内外次序.注意的点:每组数据判断前应该先重置栈.法二:类似栈思想, 将小中大左括号的个数分别用三个指标存着,遍历字符串不断更新指标,如果中途遇到不合法的括号顺序,则直接跳出循环,最后判断是否遍历完整个字符串且栈空即可.原创 2023-05-15 16:29:53 · 80 阅读 · 0 评论 -
《编程思维与实践》1072.下一位妙数
思路与最小不重复数基本一致,从最高位开始找到第一个出现9的位置,让其加1,后面全变为0即可.只需要再加一个判定条件:不能被9整除.由数学知识,一个数不能被9整除当且仅当各位数之和不能被9整除.不妨以三位数abc为例abca⋅100b⋅10cabc99a9b由9∣99a9b知9∣abc当且仅当9∣abc类似地,一个数不能被3整除当且仅当各位数之和不能被3整除.原创 2023-05-14 14:33:35 · 178 阅读 · 0 评论 -
《编程思维与实践》1068.高次方数的尾数
没啥难度,直接复用计算a的n次方的代码即可,只需注意不足N位需要补0即可.原创 2023-05-13 20:46:33 · 79 阅读 · 0 评论 -
《编程思维与实践》1059.计算a的n次方的大整数
高精度的问题统一的解决思路是用一个数组去存大整数的每一位数,运算转化为对数组的操作.可以从个位开始存(逆序),也可以从最高位开始存(顺序),以处理方便为主要考虑因素.同时可以将大整数定义为一个结构体,包含位数,数组和符号(如有必要).另外,为了能够进行代码复用,通常采用函数封装的方式.以本体为例,步骤如下:1.将a转化为大整数;2.将a不断自乘;其中大整数乘法的步骤又分为分:1.遍历两个大整数,每位的数字依次进行普通乘法加到对应的位上;原创 2023-05-11 00:57:47 · 495 阅读 · 0 评论 -
《编程思维与实践》1061.计算n!右端0的个数(II)
可以用大整数的乘法来处理,不过有些题目可以用数论的方法得到更方便的做法,以本题为例:注意到102⋅5, 所以只需要将阶乘的每一项分解成2和5的乘积形式即可,同时由于每出现一个5,必然会出现一个2,所以只需要统计出现5的个数即可.注意的点:有的数可能可以分解出多个5,如505⋅5⋅2, 所以需要不断除以5判断是否还能整除.原创 2023-05-11 15:48:25 · 321 阅读 · 0 评论 -
《编程思维与实践》1062.计算2的N次方
法一:直接复用计算a的n次方的代码即可.法二:注意到230在int(32位,第一位为符号位,231−1)的范围内,可以直接处理.注: int范围为−231231−1,大约为9位十进制整数;long long范围为−263263−1,大约为19位十进制整数.unsigned int大约为10位十进制整数,unsigned long long大约为20位十进制整数.原创 2023-05-11 15:49:19 · 339 阅读 · 0 评论 -
《编程思维与实践》1060.浮点数加法
浮点数可以分为[整数部分].[小数部分],可以将两个部分分开处理,最后再合并,但在处理四舍五入时较为繁琐,为了方便起见,这里采用将两个部分一起处理的方式:由于浮点数不超过500位:整数部分最多500位,小数部分最多500位,所以加法后的结果整数部分最多501位,小数部分最多500位.所以可以宏定义L=500,数组最大长度为2L+1,其中[0,L]存整数部分,[L+1,2L+1]存小数部分;原创 2023-05-11 15:09:49 · 326 阅读 · 0 评论 -
《编程思维与实践》1070.复数幂
abicdiac−bdadbci, 利用该公式分实部和虚部进行计算结果即可.由于涉及加减和正负号,所以在大整数结构体中加入符号参数sign,为了方便起见这里对加法和减法操作进行了一定的补充,①针对加法,令sign一开始为0,a+b有以下四种可能,需要先进行判定:1. a>0且b>0,则sign赋值为1;2. a>0且b原创 2023-05-14 01:22:59 · 264 阅读 · 0 评论 -
《编程思维与实践》1063.二进制倒置
关键点在于求出倒置后的二进制位: 由进制知识可以知道通过do while将每次%2的结果正着存就是倒置的二进制位,所以问题进而转化为如何进行大整数的除法和余数的记录.由于除法的过程中可能最高位数字变为0从而导致位数应该减1,所以逆向存(从个位开始存)更方便处理.最后再依次进行大整数的乘2+二进制位得出结果即可.其中,除法完全模拟笔除即可: 从最高位开始除以除数和上一位的余数*10之和,再记录余数即可.注意的点:1.加法有可能会导致位数增加,为了方便起见复用carry进位时可以补充对位数的处理;原创 2023-05-12 01:23:13 · 204 阅读 · 0 评论 -
《编程思维与实践》1064.A-B(Big Integer)
两个大整数做减法有可能出现结果为负的情况,因此结构体BIGINT需要补充符号位sign,因为减法是个位对齐进行操作,为了方便起见,本题还是采用逆序(个位开始)存储.注意到本题的两个整数均非负,所以不需要考虑转化为加法的情况(减负数等价于加正数).A-B有以下几种情况:1.A位数比B大,直接从个位开始减即可,不足注意借位;2.A位数比B小,结果的符号位变为-1,转化为B-A;3.A位数与B位数相同,此时需要比对A和B的大小,应该从开始比:如果从最高位开始A有一位大于B,那么就能保证A>B;原创 2023-05-12 13:47:13 · 221 阅读 · 0 评论 -
《编程思维与实践》1073.遥远距离
先从小到大排序,再复用大整数的处理方式将最大的数减去最小的数即可.注意的点:数据可能出现负整数,需要补充符号.原创 2023-05-14 15:13:36 · 56 阅读 · 0 评论 -
《编程思维与实践》1074.素数进制
结合素数进制和大整数的处理方式,之后转化为十进制数只需要采用霍纳规则即可.以1,1,1,0为例:先用一个整数数组存素数位(顺序存) 1,1,1,0;结果为((1*5+1)*3+1)*2+0=38.原创 2023-05-14 16:17:05 · 60 阅读 · 0 评论 -
《编程思维与实践》1066.最小不重复数
一般在oj上循环2⋅109次以上就会超时,所以由于这题的数据A可以很大,直接循环加一再判断会超时.优化:首先可以明确要想使不重复数尽可能小,则高位数字应该尽可能小,即,然后让后一个数字加1(保证尽可能小),这样就能保证高位数字不重复且最小,接下来只需要保证低位数字从0开始遍历,重复上述操作即可.如:6698->6700->6701.注意的点:如果复用之前对大整数的处理方式,由于加法可能会进位,逆向存较为方便,所以处理时需要注意最高位在末尾.原创 2023-05-13 19:04:30 · 632 阅读 · 0 评论 -
《编程思维与实践》1069.第一位数字
由于正整数N的N次方最大可以为108⋅108,加上数据可能有很多组,所以直接采用大整数计算次方这方法很可能超时,这里给出一种数学算法:NN10NlgN10NlgNNlgN10NlgN⋅10NlgN其中[x]表示取整,{x}表示取小数部分.那么10NlgN为10的倍数,后半部分110NlgN10且为小数,只需再取出其整数部分即为幂指函数的第一个数字(类似科学计数法).原创 2023-05-13 21:04:15 · 543 阅读 · 0 评论 -
《编程思维与实践》1067.小型组合数
所以只需要将结果依次乘m(m-1)…(m-(n-1))的每一位,然后依次除去因子1,2,3…中间步骤可能数据会超过long long的范围, 应该用unsigned long long去存.这是因为连续出现的n个数字的乘积必然会存在因子n(可用归纳法证明).记dp[n][m]=dp[n][m-1]+dp[n-1][m-1],用大整数的处理方式去计算,但需要运用组合数的递推公式。初始化dp[0][m]=1,dp[m][0]=0,之后先遍历n(从1到40)再遍历m(从1到40).注意到题目数据最大为。原创 2023-05-13 20:30:23 · 385 阅读 · 0 评论 -
《编程思维与实践》1053.字符串替换
分割字符串:反复读取内容,直到遇到数字位置,再接着读取出现次数,用一个结构体存字符片段内容和出现次数,出现次数可以用atoi来处理.原创 2023-05-07 17:15:35 · 49 阅读 · 0 评论 -
《编程思维与实践》1052.删除注释
将所有可能的情况枚举出来:1.在有效的块注释内: 有效是指块注释不在引号内,如就不是一个有效的块注释,这种情况下跳过,直到遇到*/后才重新判断情况;2.在有效的行注释内: 同理,有效是指行注释不在引号内,如就不是一个有效的行注释,这种情况下跳过(直接break);3.其余情况直接输出内容,每行结束时如果不在块注释内需要输出回车.关键在于如何判断是否有效,即判断是否在两个引号内:如中首尾两个引号中间的其余引号应该忽略,原创 2023-05-07 16:48:58 · 387 阅读 · 0 评论 -
《编程思维与实践》1051.听写字符串
不难发现,在一串字符串s的首或者尾加一个字符:当该字符大于或等于s[0]时,加在s的首位字典序更大;当该字符小于s[0]时,加在s的末尾字典序更大.编写insert函数后再判断再哪里插入字符即可.注意的点:要求用大写字母输出,而输入的字母大小写都有,不妨统一将输入的字母转化成大写字母.原创 2023-05-07 14:55:40 · 57 阅读 · 0 评论 -
《编程思维与实践》1050.最大分词法
具体步骤按题目所给的算法进行即可:1.存词典和最长词长;2.依次检索字符串s[0,L-1]…s[0,1] (依次令s[L],s[L-1]…s[1]为’\0’) 是否在词典中(遍历用strcmp判断);3.切割字符串: 可以在检索字符串后返回检索长度,利用strcpy来实现.注意的点:1.在切割字符串对s的内容进行自覆盖时最好先用一个变量去存储,避免出现问题;2.原创 2023-05-07 14:20:09 · 57 阅读 · 0 评论 -
《编程思维与实践》1049.GPS数据处理
分两步实现:1.判断是否为有效的语句:有效需要满足三个条件:①语句含$GPRMC,可以通过strstr搜索来判断;②状态已定位,可以用sscanf来读取判断;③异或结果与校验值相同,校验值的读取可以用提示中的sscanf.2.求出北京时间,直接从字段1中就可读取,只需要将小时数+8(东八区)后判断是否超过24即可(超过就减去24);原创 2023-05-06 18:26:54 · 595 阅读 · 0 评论 -
《编程思维与实践》1048.解密字符串
主要到密码是升序的,所以先将每个数字对应的个数求出,之后升序排列输出即可得到结果.求每个数字(0-9)对应的个数可以考虑每个英文单词中特有的字符(出现单次),下面提供其中一种可行的方案:z为0特有, w为2特有,u为4特有, x为6特有, g为8特有;o在0,1,2,4中都有出现, 可以通过0,2,4求出1的个数;h在3,8中都有出现, 可以通过8求出3的个数;f在4,5中都有出现,可以通过4求出5的个数;v在5,7中都有出现, 可以通过5求出7的个数;原创 2023-05-06 00:40:13 · 500 阅读 · 0 评论 -
《编程思维与实践》1047.Base64编码
法一(直接模拟):将字符数为3k,3k+1和3k+2三种情况分类讨论一下,写一个函数处理每种情况:用位运算取出二进制位,然后通过运算求出Base64编码的二进制值.法二(对法一的优化,找出三种情况处理方法的相似点,避免代码过于冗长):如上图所示,只需先优先考虑有三个字符的情况,剩下的最后处理即可.其中,%2n表示取出后n位的二进制位,这是因为N2n2k2k−1...2202n2n−1...220。原创 2023-05-05 23:58:54 · 792 阅读 · 0 评论 -
《编程思维与实践》1046.字串间距
通过字符串的搜索,找到第一次出现的位置和最后一次出现的位置,然后进行分类讨论,最后比较得到最大间距.第一次出现可以直接调用strstr函数,而最后一次出现需要使用strrstr函数(string.h里不包含),可通过反复调用strstr函数来实现.找到s1,s2第一次和最后一次出现的位置,两两进行运算有四种可能情况,再讨论s1在前还是s2在前(因为间距必须为正数),最后比较得到最大间距.原创 2023-05-04 21:55:25 · 64 阅读 · 0 评论 -
《编程思维与实践》1045.单词表
分为两个步骤处理:1.分割字符串:将所有单词存起来;2.去重后按字典序.去重有两种方法:1.先按字典序排序,之后直接输出非重复的字符串即可;2.桶排序——先将字符串去重存在一个桶里,再将桶里的非重复字符串排序输出.注意的点:单词与单词之间可能有着多个分隔字符.原创 2023-05-04 20:56:15 · 65 阅读 · 0 评论 -
《编程思维与实践》1044.数据压缩
用一个结构体存每个字符和其对应的连续出现次数(不超过255),遍历字符串判断后一个字符与前一个字符是否相同即可.原创 2023-05-04 20:29:41 · 40 阅读 · 0 评论 -
《编程思维与实践》1043.统计单词个数
有余数每行读取,所以需要gets读取后分割字符串,用一个变量存单词再判断其是否为有效单词即可.需要注意的地方:由于非有效字符可能出现大小写,所以统一将字符转化为小写字符后判断即可.原创 2023-05-04 18:16:22 · 64 阅读 · 0 评论 -
《编程思维与实践》1042.字串变换
分两步解决:1.判断是否可以通过两种变换使所有的字符串变得相同;2.在能变换的前提下使变换的次数最少。其中第一步可以将每个字符串的基底(将连续重复出现的字符视为一个字符)求出来,如: aaabbb的基底就是ab,进而只需判断基底是否相同即可;第二步考虑贪心算法,只需要将每个基底变为相同实际字符数的变换次数最少即可,转化为数学语言也就是如果一个字符a出现的次数分别为x1x2...xn, 需求出i∈12...n, 使得∣xi−x1∣...原创 2023-05-04 17:57:48 · 701 阅读 · 0 评论 -
《编程思维与实践》1041.十六进制
由于两个十六进制数不会出现首位相接的情况,所以可以直接通过找到0x出现的位置来判断是否有十六进制数:1.通过strstr函数来找寻第一个0x的位置;2.找到0x的位置后从0x后开始遍历,判断是否下一位是在0到9或者a到f之间,一旦不是就需要终止遍历;3.终止遍历后判断是否有合法的十六进制数,有则直接输出;4.迭代进行下一轮寻找(反复寻找直到后面没有出现0x);5.需要用一个变量存取总共统计的十六进制数,但它为0时需要输出-1;原创 2023-05-04 12:57:55 · 88 阅读 · 0 评论 -
《编程思维与实践》1040.字符串消除
每次消除都可能会受到第一次插入字符的影响,所以难以直接判断在哪个位置插入哪个字符后消除的字符数最多.因此考虑暴力枚举:在每个位置依此插入A,B,C 对所有情况消除的字符数进行比较,求出最大值.对于字符串的插入可以利用strcpy函数:如ABC在B前插入C,则可以通过拷贝ABC,第二位B变为C即ACC,再在第三位后拷贝BC进行覆盖变为ACBC来实现.注意的点:1.在消除字符串时需要对首位和最后一位进行单独讨论,其他位置判断与前后的字符是否一致.原创 2023-04-28 01:43:51 · 418 阅读 · 0 评论 -
《编程思维与实践》1039.字符组合
先将字符串去重+排序(保证每个组合中的字符按字典序),然后枚举出所有组合的情形,最后再进行字典序排序即可.其中字符串的去重排序可以利用ASCII码值进行桶排序,关键在于如何枚举所有组合的情形.每个位置有两种可能(选或不选),但至少要选一个,所以一共有2n−1种(减去都不选的情况)可能性.不妨将选记为1,不选记为0,那么这就刚好与二进制是对应的:以abc的所有组合为例,原创 2023-04-27 11:19:58 · 480 阅读 · 0 评论 -
《编程思维与实践》1038.排版
分两个步骤进行解决:1.在给定长度下找到每一行可以容纳的最多单词数(单词长度<M/2保证每行至少有两个单词);2.输出时补充额外的空格.其中,第一个步骤可以通过分割字符串将每个字符串存起来,再找到第一个超过给定长度M的单词来实现.主要考虑第二个步骤:要满足两个条件,空格的分布尽可能平均,同时空格尽可能靠右.如:8个空格分在3个位置则每个位置空格数为2 3 3.以8为例: 原先保证至少有一个空格 记为1 1 1 ,需要额外填充5个空格,5/3取整为1,也就是平均每个还需要补充1个空格,原创 2023-04-26 01:24:36 · 143 阅读 · 0 评论 -
《编程思维与实践》1037.一元多项式乘法
比较容易想到将步骤分为三步:1.读取多项式每项的系数(coefficient)和对应的指数(dim);2.进行多项式乘法;3.输出进行多项式乘法后的非零项系数.其中多项式乘法可以通过循环来处理,输出可以用if来判断系数是否为0,需要考虑的是如何读取多项式:ax^y(a≠±1) , ±x^y , ax(a≠±1) , ±x 和 c(常数项) 为每项可能出现的所有情况.一般情况只需要利用atoi存取系数,如果存完系数后读取的第一个字符不是x,原创 2023-04-25 21:55:11 · 242 阅读 · 0 评论 -
《编程思维与实践》1036.数组相对排序
显然是桶排序:将B出现在A中的元素放在一个桶里,没出现在A中的元素放在另一个桶里,两个桶分别排序后再输出.原创 2023-04-09 17:17:50 · 66 阅读 · 0 评论