阶段学习总结--搜索(4)

本周完成了以下几个任务:

1.搜索题专项练习

2.树的存储、查找、删除、添加、遍历

3.cf思维题结构题练习

4.kmp算法、拓扑排序的了解与实现


先来总结一下我遇到的搜索题的题型

1.连通块问题:

求细胞数量 - 洛谷

海战 - 洛谷

[USACO10OCT]Lake Counting S - 洛谷

此类题型我一般用bfs+坐标偏移量,再根据题目要求判断是否进行入队即可。

2.01背包问题

[USACO2.1]健康的荷斯坦奶牛 Healthy Holsteins - 洛谷

dfs寻求最优解,对每个状态进行递归选与不选两种状态+回溯标记。答案数组的存储、输出。

3.最短路问题

Problem - 2717

3414 -- Pots

此类题型一般是模拟+bfs,根据题意进行剪枝优化,在两方面进行优化:根据当前状态选择是否入队,哪几种方法入队,哪几种不入;每次循环先进行判断,不符合题意的直接跳过一轮(该判断与最终的结束条件不是同一个)

再来说一下这周做的部分搜索题的体会

[USACO2.1]健康的荷斯坦奶牛 Healthy Holsteins - 洛谷

每种饲料选与不选两种状态,经典dfs。

难点:数据存储,判断,递归理解。

先说数据存储:需要定义一个随条件判断更新的答案数组来存储用到了哪个编号的饲料,同时牵扯出来的问题:需要定义一个数组存储每次搜索选的饲料的编号,把它传给答案数组,而这个存编号的数组需要在递归时更新与回溯。

再来看判断:判断已选择的每种饲料总和是否分别大于最小量,牵扯出来一个问题,如何将这个总和表示为已选择的每种饲料的总和,如 选择1,3号未选2号,因此不能用简单的从1到n累加。代码如下:值得仔细体会

for(int i=1; i<=n; i++)
	{
		int sum=0;
		for(int j=1; j<=x; j++)
		sum+=b[c[j]][i];//划重点!!!!!!
		if(sum<a[i]) return false;
	}
	return true;

最后再来谈递归:

void dfs(int t,int s)
//t代表第t号饲料
//s代表当前已经选择的饲料的种数

c[s+1]=t;//c数组存储每次选的饲料的编号,t号选入
dfs(t+1,s+1);//选择t号,再继续选t+1号
c[s+1]=0;//注意这个回溯的理解!!!!!
dfs(t+1,s);//t号不选入,再继续选t+1号

虽然说一道题花了一个小时,但是收获很大。要摆脱功利性思维,并不是一晚上要搞懂多少题,写多长的博客,得到什么等级的评价,这些都不是自己的东西,只有收获到的新思路,新题型,新方法,新思维,才是自己的东西。

取数游戏 - 洛谷

搜索每个状态,dfs

难点:如何搜索所有数据,递归传参

按行搜,一行搜完(当前行数+1>col)则行数重新赋为1,列数+1.

递归判断,八个偏移量均未标记则标记当前坐标,递归搜索下一个点,并让sum加上当前坐标的数据,因此递归需要传两个内容:坐标和sum。回溯:取消标记。

两大类情况:1.八个坐标未标记:标记,递归搜下一个点,回溯。2.八个坐标至少有一个已标记,该点不选,递归搜下一个(表示为sum直接传到下一个点,不加当前坐标的数据)

全排列问题 - 洛谷

经典dfs的全排列

总结模板:

1.考虑递归需要(必须传入的改变量)传几个参数

2.设置flag标记数组,已搜过的不再搜。满足条件进行标记,递归下一个状态,回溯时取消标记

3.设置递归返回条件,如到达边界,搜完全部,不符合条件等

4.数据(答案数组)的存储与表示。

如全排列中

void dfs(int m){
    ...
    ...
    for (int i = 1; i <= n; i++) {
        if (!flag[i]) {
            store[m] = i;//注意这个m的意思
            flag[i] = true;
            dfs(m+1);
            flag[i] = false;
        }
    }
}

或者荷斯坦奶牛中的

void dfs(int t,int s)//t代表第t号饲料,s代表当前已经选择的饲料的种数
{   ...
    ...
    c[s+1]=t;//c数组存储选的饲料的编号,注意这个t和s+1的意思
    dfs(t+1,s+1);
    c[s+1]=0;
    dfs(t+1,s);
}

[USACO06OCT] Cows on Skates G - 洛谷

关于答案数组的存储还有这个题

while(!q.empty()){
    int x=q.front().first;
	int y=q.front().second;
	q.pop();
	for(int i=1;i<=4;i++){
		int xx=x+fx[i];
		int yy=y+fy[i];
		if(illegal(xx,yy)) continue;

        dist[xx][yy][0]=x;//答案数组的存储
        dist[xx][yy][1]=y;

		vis[xx][yy]=true;
		q.push(std::make_pair(xx,yy));
		if(xx==r&&yy==c) break;
	}
}

答案数组输出(暂时没有理解,后期解决会进行更新)

void WriteWay(int x,int y){
	if(!(dist[x][y][0]+dist[x][y][1])) return;
    //如果数组中为0,表示到头了,return
	WriteWay(dist[x][y][0],dist[x][y][1]);
	cout<<x<<" "<<y<<endl;//递归输出路径
}

树的存储与基本操作在这里就不多说了,感觉目前接触的主要还是递归的理解和应用,没有做题,没有自己的感悟,只有知识点,就不进行罗列了。


cf题做的比较少,浅谈一下印象最深的吧

关于下标越界的感悟

for (int i = 0; i + 1 < a.size(); i++) {
			if (a[i + 1] - a[i] == 1) ans += 2;
			else if (a[i + 1] - a[i] == 2) ans += 1;
		}

Problem - 1658A - Codeforces

遇到需要用到下标为i+1这种可能会越界的表示方法,在条件中写为i+1<n即可解决大部分情况。

(之前一直写i<n-1的形式,仍存在越界可能,直接i+1<n完事)


kmp算法体会

主要是根据最长相等前后缀让子串移动时不至于每一步都回溯,用空间换时间。


拓扑排序体会

有向无环图,即拓扑图,根据度数来进行排序

模板:

queue<-入队所有度数为0的点
while(q非空){
    t存储队头
    枚举t的所有出边t->j
    删除t->j,d[j]--;
    if(d[j]==0) queue<-j;
}

如果所有点都入队了,说明存在拓扑序列;否则不存在拓扑序列。

涉及树与图的存储的部分下周继续看资料

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 学习前端的第一个阶段学习HTML,而复盘回顾则是对所学知识的总结和反思。那么,学习HTML的复盘回顾目标可以包括以下几个方面。 首先,复盘回顾的目标是巩固和加深对HTML的理解。在学习HTML的过程中,我们通过了解HTML的语法规则、标签和属性等,掌握了如何创建网页的结构和内容。通过复盘回顾,可以巩固这些知识点,提高对HTML的理解和应用能力。 其次,复盘回顾的目标是发现和纠正自己在学习HTML过程中存在的问题和不足之处。可能在学习HTML的过程中,我们遇到了某些困难,或者对某些知识点理解不够透彻,或者在实践中出现了一些错误。通过复盘回顾,可以仔细检查自己的学习过程,找出问题所在,从而有针对性地进行纠正和改进。 另外,复盘回顾的目标是提升自己的实践能力。学习HTML不仅是理论知识的学习,更重要的是能够将所学知识应用到实际项目中。通过复盘回顾,可以回顾自己在实践中的表现,发现自己在实践中的不足之处,并通过实践的经验不断提升自己的实践能力。 最后,复盘回顾的目标还可以包括对学习HTML的感悟和未来的规划。通过复盘回顾,可以总结自己在学习HTML过程中的体会和收获,为以后的学习和发展做好规划。同时,也可以思考并规划下一个阶段学习目标和计划,为之后的学习打下坚实的基础。 ### 回答2: 学习前端第一个阶段的HTML项目的复盘回顾目标主要包括以下几个方面。 首先,目标是回顾并巩固HTML的基本知识和技能。在这个阶段,我学习了HTML的基本标签、元素和属性的用法,以及如何创建网页的结构和布局。通过实际项目的练习,我巩固了这些知识,提高了对HTML的熟练程度。 其次,目标是学会使用常用的HTML标签和元素来构建网页内容。在项目中,我学习了如何使用标题、段落、链接、图片、表格等标签和元素来创建丰富多样的网页内容。我学会了使用这些标签和元素实现文本、图片和表格的显示和排版,同时也学会了如何添加链接和导航等功能。 另外,目标是了解并掌握HTML的语义化。在项目中,我学习了如何正确选择和使用HTML标签和元素,以达到更好的语义化效果。我了解到使用适当的标签能够提高网页的可读性和可访问性,对搜索引擎优化也有一定的帮助。 最后,目标是培养自我实践和解决问题的能力。在项目中,我遇到了一些技术问题和困难,但通过查找文档、搜索和尝试,我成功地解决了这些问题。这个过程提高了我自主学习和解决问题的能力,也为接下来的学习和项目打下了坚实的基础。 总的来说,学习前端第一个阶段的HTML项目的复盘回顾目标是回顾并巩固HTML的基本知识和技能,学会使用常用的HTML标签和元素,了解并掌握HTML的语义化,以及培养自我实践和解决问题的能力。通过这个项目的学习,我对HTML有了更深的理解和掌握,为接下来的学习打下了坚实的基础。 ### 回答3: 学习前端的第一个阶段,主要是学习HTML的基础知识和技能。在完成第一个HTML项目后,进行复盘回顾是为了总结学习经验并确定进一步的目标。 首先,复盘回顾的目标是回顾项目的整体结构和设计,并评估自己对HTML基础知识的掌握程度。通过回顾项目,可以了解自己在项目中的表现,发现并改正可能存在的问题,并提升项目的整体质量。同时,回顾还可以帮助我们深入了解HTML的各种标签和属性的使用方法,以及它们之间的关系和作用。 其次,复盘回顾的目标是梳理学习过程中遇到的困难和问题。学习HTML的过程中,可能会遇到一些难以理解或掌握的概念和技术,或者在项目中遇到了一些难以解决的问题。通过回顾这些困难和问题,可以找到学习的瓶颈和不足之处,然后有针对性地进行学习和提升。 最后,复盘回顾的目标是制定下一阶段学习的目标和计划。通过回顾项目,我们可以更好地了解自己在前端学习的过程中的进步和不足,并且确定下一个阶段需要学习和提升的重点。在制定学习目标和计划时,我们可以考虑自己的兴趣和职业发展方向,并选择相应的学习资源和实践项目。 总而言之,学习前端的第一个阶段完成一个HTML项目后,进行复盘回顾的目标是总结、评估和改进学习过程和成果,并制定下一阶段学习目标和计划。通过不断的回顾和提升,我们可以逐渐成为一名优秀的前端开发者。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值