<积算成法4-c++>神秘函数逆运用(贪心、构造、字符串、模拟)

本文通过分析一道入门算法题,探讨了贪心算法的应用,特别是如何在字符串比较中找到局部最优解。作者结合个人学习经历,解释了贪心算法的定义和个人理解,以及构造在解决问题中的应用。
摘要由CSDN通过智能技术生成

本期导航

开头叨叨

正文

思路历程

知识学习

贪心算法

定义

个人理解

基本思路

与本题相关

构造

个人理解

与本题相关

结语


开头叨叨

        哈喽,各位读者朋友们大家好,我是在汤锅想着未来的任易仙~

        说来惭愧,虽然文章更新的是算法类的题目心得,却一直在入门题型徘徊,挑战难题对我来说或许是一种奢侈。其实易仙现在非常的迷茫,才学完基础c语言。现在要转向三个方向的语言学习(c++,java,python),可是多学而杂,杂而不精。进度缓慢的同时,也是加剧了学习的混乱程度。为什么我说我在“汤锅”里,很大程度上是因为自己学的很杂,什么都可以学一点,但是很难做到精益求精。这样的学习成本其实很大,不过在现在的学习之路上,我才刚刚开始。

        回想起以前写游戏攻略,做视频直播等等。很多都是开头的“闪耀”,半途的退出,坚持不下去。短期的学习强度只能提供短期的满足,而真正的成果必须是经历长期的摸爬滚打(当然本人是持续性摆烂)。我的理想是日有所进,从理论上说,持有这样的理想,应该要求自己的作品一步一步提高。不过我犯了一个错误,拿自己的“旧日成果”作为模板,以为曾经的成果就足够好了,而没有去找外界的“参考答案”,这使得我在“不思进取,复制曾经”的道路上越走越远。质量下降,持续性放弃,任务驱动而非意义驱动。单纯是为了完成这件事而完成这件事,不去思考做这件事的价值和意义。这样只会使得自己成果的价值,越来越低,越来越重复,至于没有实际意义。 

当然,路还长远,一时的空悲切并不能说明一世皆碌碌无为。我们还是需要不断拓展,不断优化自我,做出真正的改变!


正文

        今天,我找了一道入门但具有丰富知识点的题目:

(题目来源:洛谷P3742)


思路历程

        对于题目给出的一个函数,它的作用是将俩组由小写字母组成的相同长度的字符串,找到俩串字符串对应位最小的字母,组成产生出一串新的小写字母字符串,方式如图:

        弄懂了函数的功能,我本以为题目是要让我实现这样一个函数,但一比对示例输入输出,发现不对劲,好好好,我又回去读题了:

        哦!x是该函数的字符串输入值,而y是该函数的输出值,我们程序的目的是为了找到一个满足的输入值z。因为y就是原先俩个字符串的每位最小值,既然只要满足条件,那么我想了一个讨论点——x每位和y每位的比较。

        对于字符串上某一位的字符,如果x的小于y,一定不能找到z,直接返回-1即可。其他情况则直接把y的字符赋值给z即可满足条件。按照这样的思路,我写了这样的代码:

#include<iostream>
using namespace std;
int main() {
//f是一个控制最终输出的开关
	int i,n, f = 1;
	string x, y;
	char z[100];
	cin >> n >> x >> y;
	for (i = 0; i < n; i++) {
		if (y[i] > x[i]) {
			f = 0;
			break;
		}
		else
			z[i] = y[i];
	}
	if (f) {
		z[i] = '\0';
		cout << z;
	}
	else cout << -1;
	return 0;
}

利用这样的暴力一一比对赋值法,成功AC。

        我重新温习了一下我原先的讨论点,发现,代码是可以优化的——只要满足“x每位的字符不小于y”,最终直接输出y就行了。所以代码可以修改成这样:

#include<iostream>
using namespace std;
int main() {
	//f是一个控制最终输出的开关
	int i, n, f = 1;
	string x, y;
	cin >> n >> x >> y;
	for (i = 0; i < n; i++)
		if (y[i] > x[i]) {
			f = 0;
			break;
		}
	if (f) {
		cout << y;
	}
	else cout << -1;
	return 0;
}

成功AC again。


知识学习

        字符串和模拟的知识,在之前几期都入门过了。而贪心和构造,我并不是很了解,正好有一道简单题为例,那就来学习一下这俩个知识点了

贪心算法

定义

        在对问题求解时,总是做出在当前看来是最好的选择的算法。

个人理解

        对于这个算法,我的理解就是就是不做长远考虑,只考虑当下最优。使用贪心算法,首先要满足待解决的问题可以分成几个局部问题,然后根据局部最优,一步步完成整体解法。而这样得出来的解一般是一种较优解但不一定是最优解。除非满足局部问题之间毫无关联,当下做的最优决策不会影响后面局部问题的决策。如果满足局部问题毫无关联的条件,那么贪心决策得出的解很大概率就是最优解。

基本思路

⒈建立数学模型来描述问题。

⒉把求解的问题分成若干个子问题。

⒊对每一子问题求解,得到子问题的局部最优解。

⒋把子问题的解局部最优解合成原来解问题的一个解。

与本题相关

        本文章给出的题何处运用了贪心算法呢?主要思想我感觉不是非常明显,不过我们可将输出z字符串视作一个整体,而将输出每一位字符作为子问题。由于只要输出一个满足的解,那么对于每个子问题,只要找到最容易满足当位的字符,进而就可以快速解决整体问题。


构造

个人理解

        构造是一类问题的解决方式。一般这类问题具有规律性,使得数据扩大时,仍然可以找到一个比较固定的通用解法。而寻找通解的过程,就是构造。

与本题相关

        本文章给出的题本质上就是寻找每位满足条件的字符,随着字符串长度的增加,我们固然需要发现一种每位的“通解”。当我发现函数作用,逆推出x与y每位字符大小比较这个分类方向后,构造基本也就完成了。

       (参考资料来源:OI wiki,360百科“贪心(贪婪)算法词条”)


结语

        通过简单的算法题,学习算法知识点,可以更好地了解算法,更高效的加深对算法的理解与运用。同时,我希望,这一次我可以坚持下去。期待后面我可以学到更多算法知识,并将知识落到实处,实现真正的价值

看到这里如果对你有任何方面的帮助,可以点赞收藏关注一下,一起进步,一起加油!

  • 28
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值