zoukankan      html  css  js  c++  java
  • PAT 1031-1040 题解

    早期部分代码用 Java 实现。由于 PAT 虽然支持各种语言,但只有 C/C++标程来限定时间,许多题目用 Java 读入数据就已经超时,后来转投 C/C++。浏览全部代码:请戳

    本文谨代表个人思路,欢迎讨论;)

    1031. Hello World for U (20)

    题意

    将给定的字符串打印出 U 型。

    比如给定helloworld,打印出

    1
    2
    3
    4
    5
    
    
    h  d
    e  l
    l  r
    lowo
    

    设定左边的字符个数为 n1,底边字符个数为 n2,右边字符个数为 n3。需要满足 n1 = n3 = max {k|k <= n2 for all 3 <= n2 <= N} with n1 + n2 + n3 -3 = N.

    分析

    简单模拟题。

    1032. Sharing (25)

    题意

    为了节省存储空间,单词使用链表实现。比如对于loadingbeing两个单词,有如下存储结构:

    1
    2
    3
    4
    5
    
    word1 : -> [l] -> [o] -> [a] -> [d]  
                                      
                                        [i] -> [n] -> [g] -> null
                                      /
    word2 : -> [b] -> [e] -------------
    

    输入中,指定了两个单词的首字符的地址,并给出了 N (<= 105)个节点,每个节点包含:物理地址(5 位的正整数),实际存储的字符以及指向的下一个节点的地址。NULL 的地址是-1. 要求找到两单词的的公共后缀开始的地址,如果没有,则输出-1.

    分析

    既然是单词,它的长度应该是有限的,也就是链表不会出现环这种情况(实际上这里的处理方式对于有环无环都适用)。对第一个单词链表做遍历,对爬过的节点做好标记。第二个单词链表也同样做标记,一旦遇到已经标记过的节点,则该节点就是结果。

    需要注意一点:直接使用 map 做节点的存储最后一个 case 会超时。而鉴于 5 位正整数的数据量,可以直接使用数组,用空间换时间。

    1033. To Fill or Not to Fill (25)

    题意

    高速路从 A 地到 B 地,路途有许多加油站,每个加油站的油价不一样,要求计算一个最优方案,使得以最便宜的开销跑完全程。

    分析

    用贪心算法,理清贪心算法的策略:

    • 1.从 A 加油站出发,在能行走的最大范围内,如果有比 A 站汽油更便宜的 B 站,则保证在 A 站点的加油量刚好满足能到达 B 站点;如果没有比 A 站汽油更便宜的站,则在 A 加满车油行走到【从 A 能走出的范围内】油价【最便宜】的站上,再行计算。
    • 2.从 A 加油站出发,在能行走的最大范围内,如果没有其他站点,则 A.dist + 一次最大的行走距离 为 impossible 情况下的最大站点。

    注意有个陷阱:如果没有距离为 0 的加油站,则无法行驶。

    1034. Head of a Gang (30)

    题意

    『gang』翻译过来是『一伙人』。gang 的定义是一群人,至少有 3 个人,这群人中每个人之间都通过通话相连,且整个群体的通话时长超过一个阈值。整个 gang 的团体中,拥有的电话时长最长的人就是头目了。

    题目给定了 gang 的阈值 K,以及 N 个通话记录,每条记录包括主叫人、被叫人以及通话时间。要求计算出有几个 gang,并按照 gang 的头目的字母顺序排序输出头目和其中成员数量。

    分析

    本题使用 dfs 求解比较方便。dfs 能简单的实现状态值的记录,比如当前的 gang 的成员数量和权重,如果使用并查集,则相对复杂。

    需要注意的坑点:如果建立邻接表时,每个通话记录都在两人头上计算了时间积累的,那么在判定 gang 的权重值是否低于阈值的时候,需要对阈值乘以 2。

    1035. Password (20)

    题意

    给定多个字符串,按要求替换其中的某些特殊字符,并按原顺序输出。如果字符串中没有需要修改的字符,则不舒服该字符串。

    分析

    简单的 hash 实现。

    1036. Boys vs Girls (25)

    题意

    输入是一批学生的成绩,要求找出其中男生最低的成绩和女生最高的成绩,求其间的差值。如果无法计算,则输出 NA.

    分析

    简单模拟题。

    1037. Magic Coupon (25)

    题意

    背景是火星上的神奇的购物券购物策略:每张购物券上有一个整数,可正可负,商店里商品的标价也是一个整数,可正可负的。如果用正值购物券购买正值商品,则可获利两者之积;如果以负值购物券购买负值商品,也可获利两者之积;但其他情况,则会亏损。比如用面值为2的购物券购买面值为3的商品,获利6,用面值为-5的购物券购买面值为-9的商品,获利45,但如果用面值为2的购物券购买面值为-3的商品,则亏损6

    给定一组数量为 NC 购物券面值和一组数量为 NP 的商品面值,1<= NC , NP <= 105,要求计算能获利的最大值。

    分析

    同号相乘可获利,异号相乘会亏损。要使获利最大,使用贪心思想计算。实际上,不需要用完购物券或者买完商品,所以只需要将同号的数值乘积算出即可,没有更复杂的情况。

    1038. Recover the Smallest Number (30)

    题意

    给定 N(<= 10000)个不超过 8 位的非负整数,要求将其按某个顺序拼接为一个数,使其值最小。

    分析

    容易简单的以为使用字典序排列拼接,实际上有一个特殊的拼接情况需要考虑。

    比如数据32 321 3214,这是按字典序排列的,但实际上这并不是最小的拼接方式,最小的拼接方式是:321 3214 32

    比较这个实例,不难找到最小拼接的排序规律:

    • 1.两个字符串做比较时,如果其中一个字符串(a)是另一个字符串(ab)的前缀串,则需要将较长字符串(ab)除去前缀串的部分(b)与较短字符串(a)继续递归比较。比如,321 和 32,需要拿 1 和 32 做比较。又比如 323 和 32 比较,第一次拿 3 和 32 比较,第二次拿 3 和 2 按字典序比较。
    • 2.其他情况按字典序比较。

    另外需要注意的一个坑是:如果没有数据,则输出 0。

    1039. Course List for Student (25)

    题意

    给出 K(<=2500)门课程,每门课程有 Ni(<=200)名学生,学生编号为四位字符串,前三位为小写英文字母,后一位是数字。另给出 N 个需要查询的学生编号。

    要求列出对应查询编号学生的课程。如果有多个课程,需要按升序输出。

    分析

    这个题是个倒排索引的实现。不过在时间上卡的比较严。

    使用最简单的思路:map<string, vector students 倒排索引,在没有输出排序的课程列表时最后一个 case 已经超时;优化:将学生姓名的 hash 为 int,减免了 string 的匹配过程,还是超时(map 本身用红黑树实现,效率并不是特别高,还需要对每组数据进行排序),只能改变使用 map 的方式。

    最终 AC 的解法是:

    • 构建一个从学生编号字符串到 int 值的 hash 函数,在读入学生编号后,hash 到 int 值做处理。
    • 不适用 map 结构,根据学生姓名的限制,设定一个vector<int> st[26*26*26*10]的数据结构,读入时直接倒排索引插入。

    1040. Longest Symmetric String (25)

    题意

    给定一个字符串,要求输出最长的连续对称子串的长度。比如给定字符串为Is PAT&TAP symmetric?,其中最长对称子串为s PAT&TAP s,所以输出结果 11.

    分析

    这个题就是典型的 Java 实现 timeout,而 Cpp 实现轻松过的类型。需要注意两点:

    • 1.有两种对称情况,一种形如aba,一种形如abba
    • 2.循环遍历的过程,以 index 为对称中心向两边扩散比较编码实现简单也更高效。

    另外,C 读入一整行数据到 char 数组的方法可以用gets(s);

  • 相关阅读:
    【BZOJ 3090】 树形DP
    【BZOJ 2323】 2323: [ZJOI2011]细胞 (DP+矩阵乘法+快速幂*)
    【BZOJ 1019】 1019: [SHOI2008]汉诺塔 (DP?)
    【BZOJ 3294】 3294: [Cqoi2011]放棋子 (DP+组合数学+容斥原理)
    【BZOJ 3566】 3566: [SHOI2014]概率充电器 (概率树形DP)
    【BZOJ 2121】 (字符串DP,区间DP)
    【BZOJ 4305】 4305: 数列的GCD (数论)
    【UOJ 179】 #179. 线性规划 (单纯形法)
    【BZOJ 4568】 4568: [Scoi2016]幸运数字 (线性基+树链剖分+线段树)
    【BZOJ 4027】 4027: [HEOI2015]兔子与樱花 (贪心)
  • 原文地址:https://www.cnblogs.com/biaobiaoqi/p/3288700.html
Copyright © 2011-2022 走看看