点我阅读原文

最近利用闲暇时间做了一下 PTA Basic Level[1] 里的题,里面现在一共有 95 道题,这些题大部分很基础,对于刷倦了 leetcode 的小伙伴可以去里面愉快的玩耍哦。

这里我挑了三个挺有意思的题来做个简单记录,欢迎和大家一起讨论交流。

请听题:

第一题:1009 说反话

题目描述

给定一个英语句子,各个单词之间用空格分隔。要求你编写程序,将句中所有单词的顺序颠倒输出。

输入示例

Hello World Here I Come

输出示例

Come I Here World Hello


没骗你吧,是不是很简单。这道题我们确实可以很容易的解决,但你的思路是什么呢?你设计的算法很完美么?

相信会有一部分小伙伴的思路是这样滴: 首先string来保存输入的句子,再split分隔提取单词,将单词保存在vector中,最后倒序输出。

vector<string> split(string sentence) {
//将句子中的单词提取,返回
}
int main() {
string sentence;
cin >> sentence;
vector<string> allWords = split(sentence);
for (string word : allWords) {
cout << word << ' ';
}
return ;
}

这样没毛病哈,我第一次就是这么干的。但对于这种简单题,这样做显得太麻烦了,然后我在网上看到了这段代码:

int main() {
stack<string> v;
string s;
while(cin >> s) v.push(s);
cout << v.top();
v.pop();
while(!v.empty()) {
cout << " " << v.top();
v.pop();
}
return ;
}

当时真的惊艳到我了,上面代码充分利用了cin以空格分隔各个变量输入的特点,直接提取到了各个单词。

之后巧妙利用栈后进先出的特点,将单词依次压入stack,最后再依次弹出,就得到了逆序的单词序列,这两行代码用的着实巧妙!

第二题:1060 爱丁顿数

题目描述

据说天文学家爱丁顿为了炫耀自己的骑车功力,定义了一个“爱丁顿数” E ,即满足有 E 天骑车超过 E 英里的最大整数 E。

现给定某人 N 天的骑车距离,请你算出对应的爱丁顿数 E(≤N)。

输入第一行给出一个正整数 N (≤10^5),即连续骑车的天数;第二行给出 N 个非负整数,代表每天的骑车距离。

在一行中输出 N 天的爱丁顿数。

输入示例

10

6 7 6 9 3 10 8 2 7 8

输出示例

6


看到 N (≤10^5) 我以为不能暴力求解,但旺旺没想到,暴力竟然也能过。首先我们来看一下暴力思路是咋样的。

通过题目我们可以确定 E 的取值范围是 0 ~ N,也就是说我们要在0 ~ N中搜索一个符合条件的尽可能大的数。

暴力思路就是这样的:

for (int i = N; i >= ; i--) {
//判断i是否符合条件
if (isOk(i, a, n)) {
cout << i;
break;
}
}

这个时间复杂度是 On^2 ,因为外层for的遍历需要 n,判断每个 i 是否符合条件也需要 n。

要优化其实也很简单。既然是要在0 ~ N的空间中搜索,而且0 ~ N也是单调的,那正好符合二分的使用条件。我们就可以用二分来代替第一层for循环,这样时间复杂度就是 O(nlog^n) 了。

二分优化后的代码:

// 判断k是否符合条件
bool isOk(int k, int a[], int n) {
int cnt = ;
for (int i = ; i < n; i++)
if (a[i] > k)
cnt++;
return cnt >= k ? true : false;
}
int main() {
int n, a[];
cin >> n;
for (int i = ; i < n; i++)
cin >> a[i];
int l = , r = n;
while (l <= r) {
int mid = l + ((r - l) >> );
if (isOk(mid, a, n))
l = mid + ;
else
r = mid - ;
}
cout << r;
return ;
}

像这种使用二分优化搜索空间的题型 leetcode 上也有很多,比如 875. 爱吃香蕉的珂珂[2],1011. 在 D 天内送达包裹的能力[3],1231. 分享巧克力[4],对这块不熟悉的小伙伴可以去做做。

第三题:1070 结绳

题目描述

给定若干段绳子,你需要把它们串成一条绳。每次串连的时候,是把两段绳子对折,再套接在一起。这样得到的绳子又被当成是另一段绳子,可以再次对折去跟另一段绳子串连。每次串连后,原来两段绳子的长度就会减半。

给定 N 段绳子的长度,你需要找出它们能串成的绳子的最大长度。

输入示例

8

10 15 12 3 4 13 1 15

输出示例

14


经典算法中有两类算法特别考验解题思维,一是动态规划,二是贪心思想。

这道题就是一道简单的贪心题。根据题目的意思,我们需要找到一种串连方式,使得最终得到的绳子的长度最长,也就是使得 N 段绳子损失的长度最小。

那么如何尽可能减小绳子长度的损失呢?每次尽可能的选用短绳对折连接,从而避免长绳对折,采用这种方式进行连接绳子长度损失是最小的。

在程序中我们可以使用优先队列priority_queue让队首元素保持值最小,代码如下:

int main() {
priority_queue<int, vector<int>, greater<int>> q;
int n;
cin >> n;
for (int i = ; i < n; i++) {
int v;
cin >> v;
q.push(v);
}
while (q.size() > ) {
int l1 = q.top(); q.pop();
int l2 = q.top(); q.pop();
q.push((l1 + l2)/);
}
cout << q.top();
return ;
}

对贪心不熟悉的小伙伴可以看看这篇文章:初识贪心思想

总结

这三道题不会很难吧,但要写出令人眼前一亮的代码不仅要有扎实的算法基础,还要能够灵活的使用数据结构。所以在做题的时候要多思考,多总结!

今天是小年,祝大家小年快乐!

参考资料

[1]

PTA Basic Level: https://pintia.cn/problem-sets/994805260223102976/problems/type/7

[2]

875. 爱吃香蕉的珂珂: https://leetcode-cn.com/problems/koko-eating-bananas/

[3]

1011. 在 D 天内送达包裹的能力: https://leetcode-cn.com/problems/capacity-to-ship-packages-within-d-days/

[4]

1231. 分享巧克力: https://leetcode-cn.com/problems/divide-chocolate/

来自PTA Basic Level的三只小野兽的更多相关文章

  1. PTA(Basic Level)1006.Sign In and Sign Out

    At the beginning of every day, the first person who signs in the computer room will unlock the door, ...

  2. PTA(Basic Level)1020.月饼

    月饼是中国人在中秋佳节时吃的一种传统食品,不同地区有许多不同风味的月饼.现给定所有种类月饼的库存量.总售价.以及市场的最大需求量,请你计算可以获得的最大收益是多少. 注意:销售时允许取出一部分库存.样 ...

  3. PTA(Basic Level)1023.组个最小数

    给定数字 0-9 各若干个.你可以以任意顺序排列这些数字,但必须全部使用.目标是使得最后得到的数尽可能小(注意 0 不能做首位).例如:给定两个 0,两个 1,三个 5,一个 8,我们得到的最小的数就 ...

  4. PTA --- Basic Level 1009 说反话

    1009 说反话 (20 point(s))   给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出. 输入格式: 测试输入包含一个测试用例,在一行内给出总长度不超过 80 的字符串.字符串由 ...

  5. PTA(Basic Level)1024.科学计数法

    科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式 [+-][1-9].[0-9]+E[+-][0-9]+,即数字的整数部分只有 1 位,小数部分至少有 1 位,该数字及其指 ...

  6. PTA(Basic Level)1046.划拳

    划拳是古老中国酒文化的一个有趣的组成部分.酒桌上两人划拳的方法为:每人口中喊出一个数字,同时用手比划出一个数字.如果谁比划出的数字正好等于两人喊出的数字之和,谁就赢了,输家罚一杯酒.两人同赢或两人同输 ...

  7. PTA(Basic Level)1060.爱丁顿数

    英国天文学家爱丁顿很喜欢骑车.据说他为了炫耀自己的骑车功力,还定义了一个"爱丁顿数" E ,即满足有 E 天骑车超过 E 英里的最大整数 E.据说爱丁顿自己的 E 等于87. 现给 ...

  8. PTA(Basic Level)1077.互评成绩计算

    在浙大的计算机专业课中,经常有互评分组报告这个环节.一个组上台介绍自己的工作,其他组在台下为其表现评分.最后这个组的互评成绩是这样计算的:所有其他组的评分中,去掉一个最高分和一个最低分,剩下的分数取平 ...

  9. PTA(Basic Level)1027.打印沙漏

    本题要求你写个程序把给定的符号打印成沙漏的形状.例如给定17个"*",要求按下列格式打印 ***** *** * *** ***** 所谓"沙漏形状",是指每行 ...

随机推荐

  1. java数组简介

    数组(Array)是Java 语言中内置的一种基本数据存储结构,通俗的理解,就是一组数的集合,目的是用来一次存储多个数据.数组是程序中实现很多算法的基础,可以在一定程度上简化代码的书写. 备注: 数组 ...

  2. pycharm下的多个python版本共存(二)

    上一篇博文介绍了在windows下同时安装python2和python3.而在工作的过程中,我习惯于用pycharm作为IDE.本文将记录如何在pycharm中选择python版本,并给相应的版本安装 ...

  3. H5 数据存储localStorage

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. H3C 环路避免机制二:水平分割

  5. java 声明多个泛型类型和通配符

    若一个类中多个字段需要不同的泛型声明,则在声明类的时候指定多个泛型类型即可: 格式: public interface IDAO<PK, T> { PK add(T t); void re ...

  6. PhpStorm terminal无法输入命令的解决方法

    下面小编就为大家带来一篇PhpStorm terminal无法输入命令的解决方法.小编觉得挺不错的,现在就分享给大家,也给大家做个参考.一起跟随小编过来看看吧   在使用PhpStorm时,点击下面的 ...

  7. 机器学习——HMM & CRF

    整理自: https://blog.csdn.net/woaidapaopao/article/details/77806273?locationnum=9&fps=1 HMM CRF HMM ...

  8. 2019-9-24-dotnet-remoting-抛出异常

    title author date CreateTime categories dotnet remoting 抛出异常 lindexi 2019-09-24 15:39:50 +0800 2018- ...

  9. CF526F Pudding Monsters

    CF526F Pudding Monsters 题目大意:给出一个\(n* n\)的棋盘,其中有\(n\)个格子包含棋子. 每行每列恰有一个棋子. 求\(k*k\)的恰好包含\(k\)枚棋子的子矩形个 ...

  10. 服务端CURL请求

    服务端与服务端之间,也存在接口编程. 比如我们网站服务端,需要发送短信.发送邮件.查询快递等,都需要调用第三方平台的接口. 1.php中发送请求 ①file_get_contents函数 :传递完整的 ...