来自PTA Basic Level的三只小野兽
最近利用闲暇时间做了一下 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的三只小野兽的更多相关文章
- 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, ...
- PTA(Basic Level)1020.月饼
月饼是中国人在中秋佳节时吃的一种传统食品,不同地区有许多不同风味的月饼.现给定所有种类月饼的库存量.总售价.以及市场的最大需求量,请你计算可以获得的最大收益是多少. 注意:销售时允许取出一部分库存.样 ...
- PTA(Basic Level)1023.组个最小数
给定数字 0-9 各若干个.你可以以任意顺序排列这些数字,但必须全部使用.目标是使得最后得到的数尽可能小(注意 0 不能做首位).例如:给定两个 0,两个 1,三个 5,一个 8,我们得到的最小的数就 ...
- PTA --- Basic Level 1009 说反话
1009 说反话 (20 point(s)) 给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出. 输入格式: 测试输入包含一个测试用例,在一行内给出总长度不超过 80 的字符串.字符串由 ...
- PTA(Basic Level)1024.科学计数法
科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式 [+-][1-9].[0-9]+E[+-][0-9]+,即数字的整数部分只有 1 位,小数部分至少有 1 位,该数字及其指 ...
- PTA(Basic Level)1046.划拳
划拳是古老中国酒文化的一个有趣的组成部分.酒桌上两人划拳的方法为:每人口中喊出一个数字,同时用手比划出一个数字.如果谁比划出的数字正好等于两人喊出的数字之和,谁就赢了,输家罚一杯酒.两人同赢或两人同输 ...
- PTA(Basic Level)1060.爱丁顿数
英国天文学家爱丁顿很喜欢骑车.据说他为了炫耀自己的骑车功力,还定义了一个"爱丁顿数" E ,即满足有 E 天骑车超过 E 英里的最大整数 E.据说爱丁顿自己的 E 等于87. 现给 ...
- PTA(Basic Level)1077.互评成绩计算
在浙大的计算机专业课中,经常有互评分组报告这个环节.一个组上台介绍自己的工作,其他组在台下为其表现评分.最后这个组的互评成绩是这样计算的:所有其他组的评分中,去掉一个最高分和一个最低分,剩下的分数取平 ...
- PTA(Basic Level)1027.打印沙漏
本题要求你写个程序把给定的符号打印成沙漏的形状.例如给定17个"*",要求按下列格式打印 ***** *** * *** ***** 所谓"沙漏形状",是指每行 ...
随机推荐
- 试用ZooKeeper
ZooKeeper下载 通过ZooKeeper官网下载最新的稳定版本 解压ZooKeeper到某个目录,其目录结构为: 运行环境要求 系统环境 ZooKeeper对于市面上各种操作系统都有了不错的支持 ...
- React 蚂蚁金服+ Antd 组件使用技巧
安装antd 组件 yarn add antd -D import { Card,Button,Table,From,Modal ,Select } from 'antd'; .引入就可以使用了 ...
- linux模块参数
驱动需要知道的几个参数因不同的系统而不同. 从使用的设备号( 如我们在下一章见到的 ) 到驱动应当任何操作的几个方面. 例如, SCSI 适配器的驱动常常有选项控制标记命令队列 的使用, IDE 驱动 ...
- 配置DNS代理
- Node.js Windows Binary二进制文件安装
1.下载文件 安装包的下载路径为:https://nodejs.org/en/download/ 选择你需要的版本,这里我选择了 Windows Binary 64-bit 版本. 2.配置npm安装 ...
- C# 已知点和向量,求距离的点
已知一个点 P 和向量 v ,求在这个点P按照向量 v 运行距离 d 的点 B . 已经知道了一个点 P 和他运动方向 v ,就可以通过这个求出距离点 P 为 d 的点 B. 首先把 v 规范化,规范 ...
- 2018-2-13-Xamarin-Forms-进度条控件
title author date CreateTime categories Xamarin Forms 进度条控件 lindexi 2018-2-13 17:23:3 +0800 2018-2-1 ...
- Linux 2>&1的意思
2>&1的意思是将标准错误(2)也定向到标准输出(1)的输出文件中. 我们来具体了解下:Linux 中三种标准输入输出,分别是STDIN,STDOUT,STDERR,对应的数字是0,1, ...
- python关于MySQL的API -- pymysql模块
1.模块安装 pip install pymysql 2.执行sql语句 import pymysql #添加数据 conn = pymysql.connect(host='127.0.0.1', p ...
- .data()与.detach()的区别
.data()和.detach()都可以获取Variable内部的Tensor,但.detach()更加安全 https://zhuanlan.zhihu.com/p/38475183