点我阅读原文

最近利用闲暇时间做了一下 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. linux 字符设备注册

    如我们提过的, 内核在内部使用类型 struct cdev 的结构来代表字符设备. 在内核调用你 的设备操作前, 你编写分配并注册一个或几个这些结构. [11] 11为此, 你的代码应当包含 < ...

  2. 【t046】牛跳

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] John的奶牛们计划要跳到月亮上去.它们请魔法师配制了P(1 <= P <=150,000 ...

  3. HDU 1024 Max Sum Plus Plus (动态规划 最大M字段和)

    Problem Description Now I think you have got an AC in Ignatius.L's "Max Sum" problem. To b ...

  4. Linux 内核PC/104 和 PC/104+

    当前在工业世界中, 2 个总线体系是非常时髦的: PC/104 和 PC/104+. 2 个在 PC-类 的 单板计算机中都是标准的. 2 个标准都是印刷电路板的特殊形式, 包括板互连的电子的/机械的 ...

  5. 2019前端学习路线心得-黑马程序员pink老师

    在规划之前先给大家分享几点心得哈: 1. 学习,特别是在线学习,是非常辛苦的事情,为了少走弯路, 所以一定要系统学习,多借鉴与前辈们总结出来的经验. 2. 不要相信任何说 一周掌握 css, 一周学完 ...

  6. ie6,7不支持display:inline-block;

    解决方案: display:inline-block; *display:inline;*zoom:1; ie6:* _ ,ie7:*

  7. Jenkins+Git+Gitlab+Ansible实现持续集成自动化部署静态网站(一)

    在之前已经写了关于Git,Gitlab以及Ansible的两篇博客<Git+Gitlab+Ansible剧本实现一键部署Nginx--技术流ken>,<Git+Gitlab+Ansi ...

  8. nor flash之频率限制

    背景 支持一款nor flash时,出于性能考虑,一般会查看其nor支持的最高频率以及主控端spi控制器的最高频率,以选择一个合适的运行频率. 对于一款主控支持多款flash的情况,还得考虑好兼容性等 ...

  9. jquery中报错Uncaught ReferenceError: $ is not defined的解决办法

    jquery中报错提示为:Uncaught ReferenceError: $ is not defined 这个错误的原因就是你没有引入jquery库文件或者引入的路径不对造成的

  10. 前端Tips#2 - 将 arguments 转换成Array的最佳实践

    本文同步自 JSCON简时空 - 技术博客,点击阅读 视频讲解 文字讲解 1.先讲结论 有很多种方式将 arguments 转换成数组,那么哪一种方式是最优的? 为节约大伙儿的时间,这里先说一下结论: ...