第七周总结

这周接近尾声了,与其他周不同的是这周没打比赛,总感觉缺了点啥。这周经历的最大的事就是发烧吧,从星期五中午开始,这两天就没咋学,可想而知在空余时间最多的周末没学习学的内容肯定不是特别多,但是毕竟学了这么久的搜索,尽管这个星期用的时间比上个星期短很多,但是看的内容却和上个星期差不多,真的是感觉越看越快,有些东西也了解的更深了一些。现在解释深搜和广搜的两个过程图已完全刻在脑子里了。这周看博客还出现了一些新的概念。这个星期去参加ACM协会的面试了,问了俩问题第一个问题是vector原理,我第一个想到的是程序设计B类中的new我感觉他俩原理差不多都是申请空间,第二个问题是广搜实现用的queue可否换为栈,当时听完我的第一反应是不可以,当时对栈的理解只是后进先出,对队列的理解在先进先出上,随着面试的进行我发现有人却说可以,我找了很多资料但是都并没有了解到相关内容,我意识到自己掌握的知识实在是太少了,虽然说知识是没用的,但是要获得有用的东西,必须要走有知识这一步。

总结一下我这星期看的题思路。

1、最大食物链计数 - 洛谷

看题解时了解到新的概念拓扑排序,用的是bfs。

题意:给出两个正整数 n,m,表示生物种类 n 和吃与被吃的关系数 m

接下来 m行,每行两个正整数,表示被吃的生物A和吃A的生物B

求食物链条数。

思路:要创建两个数组,分别用于储存不同生物在A和B位置出现的次数,bfs首先要做的工作是,应该如何开始,起点是啥,m行数据中B的根据食物链定义,可知一定不含生产者,即出现次数为0的生物,故寻找出来可作为bfs起点,(但是我想的是为啥不从最高营养级取,只要m行数据中A的出现次数为零的不就行了,现在想确实可以,for里面套while,找到生物量为0的,但是面临一个问题是,现在学的内容都是从一个点出来分出多个点,该如何从多个点到一个点确实还不知道咋实现,我想应该涉及方向的问题,有可能也根本无法实现,就算是实现也是代码又长又难懂),要考虑如何知道当下营养级所形成的链条数呢?当下营养级形成的链数是所有上一个营养级所形成链的总和,其实就和递归思想差不多,那如何设置条件使得ans链条能够变化呢?当确定一个生物后,让m行数据中B中出现该生物的次数为0,且要保证A中不含有该生物,即可这个营养级所形成的链条数加入到ans中去。还有下面这个代码中continue//有没有都行,我感觉加上好可以减少时间复杂度。

#include<bits/stdc++.h>
using namespace std;
int n,m,ru[5005],chu[5005],a,b,f[5005],ans;
int mp[5005][5005];
queue<int> q;
int main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		scanf("%d%d", &a, &b);
		mp[a][b]=1;//记录关系
		chu[a]++;
		ru[b]++;//记录入度和出度
	}
	for(int i=1;i<=n;i++){
		if(ru[i]==0) {
			f[i]=1;
			q.push(i);//入度为零的入队
		}
	}
	while(!q.empty()){//队列不为空
		int a=q.front();
		q.pop();//出队
		for(int k=1;k<=n;k++){
			if(mp[a][k]==0)continue;
			f[k]+=f[a];//更新
			f[k]%=80112002;
			ru[k]--;//食物少了一个
			if(ru[k]==0){//入队为零才入队
				if(chu[k]==0){
					ans+=f[k];
					ans%=80112002;
                    continue;//有没有都行
				}
				q.push(k);
			}
		}
	}
	cout<<ans; 
}

2、​​​​​​奇怪的电梯 - 洛谷

这道题我第一眼看到的时候我想用dfs完全可以做,因为深搜把所有情况都求出来了,所以求最短路径加上判断条件就可以求最短路径了。我就看了如何用广搜解决,发现这就是一道经典的广搜题。这道题从时间来看的话要用bfs,对于任意数据来说。

题意:有N层楼,每层楼都有一个数字K,在该楼层只能向下或向上走K步,求所给楼层初始位置到最后的位置需要至少摁多少次按钮。

思路:这队列数据一次肯定要有俩,一个是当前楼层另一个是摁按钮次数,自然想到了struct,用来定义队列变量,就上下两种情况进行找即可,就是正常bfs应用。

3、[USACO06OCT] Cows on Skates G - 洛谷

题意:r行c列的矩阵求一种路径,输出经过点的坐标,“*”不可走,“.”可走;

思路:也可算是一个求步数的题用dfs不用回溯,dfs(x,y,step),设置就这样设置,(x,y)是对当下这个进行搜索看看是否符合条件,以前看的题是对路径这个本体进行处理,而这里的路径作为数组下标来标记,当下点的坐标。这道题其实完全可以用bfs写,但是从时间这方面来看的话,并不一定比dfs快。

4、[NOIP2017 提高组] 奶酪 - 洛谷

这道题题解又出现了新的名词并查集,反正看细看,就用搜索的内容解决的。

题意:有个大奶酪,高度为h,长度和宽度无限长,奶酪有洞,现给你洞的球心坐标和半径,洞相通的条件为球的相切和相交的情况,一个小鼠可以从下表面到上表面吗。

思路:要先找到与下表面相通的洞,即z-r<=0即可,接下来搜索就行,搜索结束(1)找到z+r>=h时结束;(2)全部搜索完都没找到也结束;下面这个代码要把第三行像下面这样放在循环里面,有可能减少时间复杂度。

for(int i=1;i<=n;i++){
            if(!vis[i] and z[i]-r<=0) search(i);
            if(pd==1){ cout<<"Yes"<<endl; break;}
        }

如何找到两洞相连呢?俩圆心距离要小于等于半径的二倍,下面的函数可以使代码写的好看一点,且更有条理性。

double dis(int a,int b){
    double x1=(double)x[a],y1=(double)y[a],z1=(double)z[a];
    double x2=(double)x[b],y2=(double)y[b],z2=(double)z[b];
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
}

总结:这个星期主要还是看了广搜和深搜的内容,前面几个星期都没好好的写过代码,想下个星期去自己亲手做一些广搜和深搜的题目,现在感觉这两部分知识大部分应该都掌握了,感觉做题的话,要多看一些思维题,努力提升自己的思维,希望自己能一直坚持下去。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值