//题目链接https://www.patest.cn/contests/pat-b-practise;
//语言:C
//一起刷,讨论的dalaoes私信加好友!评论!
//ide:vs2017,VS牛逼!
//所有代码都是能在VS下正常通过编译而非正常提交到PAT,正常提交仅略微修改适应提交(具体就是一些_s,C和C++的部分差异问题,详见专栏中某些前文pat刷题记)
//代码运行时间来源于提交(经多次提交确认取非香港主机的结果)
//持续更新中~
//通过率参考:
#include <stdio.h>
int main()
{
1045:
写完后我又想了想这题为什么0.18,挖了一个小坑(还拉你一把)肯定不是主要原因(后面再写),可能是正好打中了我们的惯性思维;
这题摆明了就是比一下前面数的最大值,后面数的最小值。两个条件都ok就存到一个新的数组里,然后再排序。然而10W数据量200ms,怎么操作才能得到前面的最大值和后面的最小值?硬来是断然不行的,每次都要遍历所有的n^2+,断然超时。进行排序也不行,整个数组分成了两节还要除去一个元素,势必要涉及数组元素的删除重组--这不是C干的事儿。想过计算,感觉也并没有什么头绪。剩下就剩一个双向递归--我觉得这不是人干的事儿,而且还很有可能也超时。似乎走进了死胡同?;
后来冷静下来就发现自己掉进了自己的惯性思维:沉迷于一步到位的优化。什么意思呢?假设要录入两个等长的数组,我恨不得就遍历一圈,一次录两个--这样只录一圈就录好了。这确实在复杂度上有了优化,但我要付出非逻辑顺序的代价(不是一次打完数组a再数组b,而是一个a[i]一个b[i}往里输);插排和冒泡对每个数都一次到位了,也不需要太多额外空间,但相比不是一次到位的快排而言就慢多了。算法从来没有完爆,只有平衡和选择;
简而言之,这题的思路就类似于把冒泡改快排--可以不要一次到位,可以给你点空间,但你得整快点:
将原来数组定义成结构体,每个搭个bool型的小尾巴(写C++的数据库老师新讲的,感觉很适合这里和cmp就用了,省空间)。首先从头到尾遍历一圈,将左边的最大值大于这个数的bool值改成false,再从尾到头遍历一圈,将右边最小值小于这个数的改成false。于是这个题目就改成了德才论([新手][PAT乙级][C]刷题记1013-1016--1015:qsort多条件排序);
于是(?)考虑优化,第一遍遍历可以直接跟着录入,时间又短了,哇咔咔;
我是事先注意看了这个0.18的,一全想通感觉整个人都飘了。好久没写过cmp(一直对这个似懂非懂每次对着写的),这次写一个陌生样式的,就跟着感觉走居然直接写对了,感觉自己好像灵魂出窍换了个人一样;
在后面具体过程就不写了,脑子里就一把过三个字了。最后调试了下没有点的:2n2 1结果输出0n1,(Ak什么都算到了.jpg)于是加了个等于0就直接跳过输出模块return 0;(n是回车换行的意思别想多了)
提交气死咱了,掉了个活久见的错误:
仔细看了一圈代码,感觉完全没有格式错误的点,重新看题,他没有怎么说为0如何,就说第一行第二行,感觉应该是这个0也要来第二行直接n吧,遂加一个printf("n");,AC;
C++AC,交C报unknown type name 'bool',遂百度之,error: unknown type name ‘bool’,加一行#include <stdbool.h>,AC;
代码(C 32ms 1900kb, C++ 32ms 1896kb 测试点2:没有主元符合条件)
#include
1046:
感觉没什么好说的,简单说下优化(其实并不需要,400ms)的思路:
1.不要存数据,判断一次类似哈希加一下就好;
2.判断胜负:先判断两个是否相等,再判断相加的和等于A或者B,相对于最后判断相等再另外操作复杂度低;
代码(C 3ms 384kb,C++ 3ms 480kb)
#include
1047:
1047理论上说这题可以不走哈希(最多1W,1k组,如果数据量小而散哈希最后取1000个里的最大值相当亏),不过写起来简单无脑啊!反正400ms无人权,超不了;
中间第二个值其实是无效的干扰条件,直接%*d喂苟;
代码(C 4ms 384kb,C++ 4ms 480kb)
#include
1048:
这题毒性堪比福尔摩斯,我这么说应该没有人不服吧。(严肃到没有分号)
扒一扒这题的坑(同志们,看到了作者,一定要警惕啊!!):
1.专打VS党,疯狂报段错误(我被坑了两次)
这个点就在于你录入字符串时候本来录入的句子scanf_s("%s %s", code, 101, str, 101);交上去你如果只去了_s(还要去掉限定的长度)一般会报编错:函数参数多了,但这里他报段错误。我看的满脸问号,折腾了以下。到最后我也不知道为什么会报段错误。--我想这可能是他们挖坑的时候踩出来的一个坑吧?;
2.
对奇数位,对应位的数字相加后对13取余——这里用 J代表10、Q代表11、K代表12;
听说你扑克玩的很6?
3.
对 奇数位,对应位的数字相加后对13取余——这里用J代表10、Q代表11、K代表12;对 偶数位,用B的数字减去A的数字,若结果为负数,则再加10。
什么是奇数位?难道不是这个数是奇数,就是奇数位吗?后面还有一句看似莫名其妙,其实含蓄的话
这里令个位为第1位。
//这里还好的一点是,如果你仅仅没看到这里测试例子会发现问题。如果万一像我一样同时写错了去判断A的数字的奇偶的话,因为A是1234567,你就会这样,几乎万劫不复:
如果说上面123都是我自己的问题的话,那么还有;
4.
看例子你明白了如果B比A长,长的部分不用处理。那么如果A比B长,就安心处理B的呢几位就好?;
这个题最坑的就是你以为如果A的位数比B长就不用管了,其实还是得把B补成跟A一样长才行。--PAT乙级-1048. 数字加密(20)-native
5.
什么,也就这样了?现在我们考虑以下情况:
输入01 01会发生什么?;
输入在一行中依次给出A和B,均为不超过100位的正整数,其间以空格分隔。
诶,我一直都说这是正整数啊喂!你要咋整是你的事儿,但我就100位了,有本事你咬我?你说他是字符串就字符串?你哪里看到我提他是字符串了?; (@陈越姥姥 如果这里没设点的话设一个呗,指不定能超越福尔摩斯啊!(奸笑.jpg))
我是真的佩服这0.24,他们到底经历了怎样的折磨才能AC;
我大概的经历:看出12,被3坑了->看出3,被4坑了->一晚上没睡好,想出可能是5的问题,重写,继续被4坑(关于5有没有设点,其实我是不知道的,因为我改了之后提交跟之前结果完全一样,但不排除这里设点的可能)->百度得到4,稍微修改AC;
代码(16/20, 掉测试点2 5,包括之前没有注意5的尸体,AC代码思路也基于此)
#include
AC代码(基于上面胡乱改的,可能不太合乎优化,难受不想想了)(C 3ms 384kb,C++ 3ms 480kb)
#include
//回头看配图,感觉好亲切;
return 0;
}
1>------ 已启动生成: 项目: , 配置: Debug Win32 ------
1>.cpp
1>已完成生成项目“.vcxproj”的操作。
========== 生成: 成功 1 个,失败 0 个,最新 0 个,跳过 0 个 ==========