点我阅读原文

最近利用闲暇时间做了一下 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. 试用ZooKeeper

    ZooKeeper下载 通过ZooKeeper官网下载最新的稳定版本 解压ZooKeeper到某个目录,其目录结构为: 运行环境要求 系统环境 ZooKeeper对于市面上各种操作系统都有了不错的支持 ...

  2. React 蚂蚁金服+ Antd 组件使用技巧

    安装antd 组件 yarn add antd -D import {  Card,Button,Table,From,Modal ,Select  } from 'antd'; .引入就可以使用了 ...

  3. linux模块参数

    驱动需要知道的几个参数因不同的系统而不同. 从使用的设备号( 如我们在下一章见到的 ) 到驱动应当任何操作的几个方面. 例如, SCSI 适配器的驱动常常有选项控制标记命令队列 的使用, IDE 驱动 ...

  4. 配置DNS代理

  5. Node.js Windows Binary二进制文件安装

    1.下载文件 安装包的下载路径为:https://nodejs.org/en/download/ 选择你需要的版本,这里我选择了 Windows Binary 64-bit 版本. 2.配置npm安装 ...

  6. C# 已知点和向量,求距离的点

    已知一个点 P 和向量 v ,求在这个点P按照向量 v 运行距离 d 的点 B . 已经知道了一个点 P 和他运动方向 v ,就可以通过这个求出距离点 P 为 d 的点 B. 首先把 v 规范化,规范 ...

  7. 2018-2-13-Xamarin-Forms-进度条控件

    title author date CreateTime categories Xamarin Forms 进度条控件 lindexi 2018-2-13 17:23:3 +0800 2018-2-1 ...

  8. Linux 2>&1的意思

    2>&1的意思是将标准错误(2)也定向到标准输出(1)的输出文件中. 我们来具体了解下:Linux 中三种标准输入输出,分别是STDIN,STDOUT,STDERR,对应的数字是0,1, ...

  9. python关于MySQL的API -- pymysql模块

    1.模块安装 pip install pymysql 2.执行sql语句 import pymysql #添加数据 conn = pymysql.connect(host='127.0.0.1', p ...

  10. .data()与.detach()的区别

    .data()和.detach()都可以获取Variable内部的Tensor,但.detach()更加安全 https://zhuanlan.zhihu.com/p/38475183