福州夏令营第二天

    今天已经是第二天了,今天我们学习了BFS,说是学习,不如说是复习吧,但也收获了很多。除了BFS外,我们还学了一些深度优先搜索的剪枝,这真的是一样非常玄学的东西。讲了一些的题目,有一些题目非常的简单,我以前的基础是可以完全理解并解决的。但同时,我们也讲了一些难题,这一些题目当时讲得时候我可能有一些茫然,所以课后,就不得不去自己思考一下了。

    先讲一道BFS的题目吧,这是我们的老师先抬出来的,可以说是学BFS的基础题吧。

    骑士救公主(题目忘了,救勉强来凑合一下吧)

    题目描述大概就是一个骑士(R)要在一个n*m的方格中移动到公主的位置(A),每一次移动都需要花费1的时间,这个方格内还有非常多的不能通过的墙(#),普通的道路(.)。同时,一路上还有非常多的守卫(R),骑士移动到守卫的位置必须打败守卫,但需要消耗1的时间。求最短的时间。如果无法到达,就输出NO。

    冷静分析:

    竟然是找最短的,那么求的一定是最优解。我们的BFS正是用来求最优解的大宝贝。但是如果用DFS一条路走到黑的话,时间复杂度太高,会用大把的时间来走错误的路,最后的结果也就可想而知(嘿嘿嘿)。知道了算法,那就好办了。

    老师给我们讲了一遍,不过我觉得老师讲得很清晰,但是我还是想要用自己的方法:我们可以把整个方格用int类型存储起来,如果是墙的话,就记为0,如果是骑士,普通的路或者公主的话,就记为1,如果是守卫的话,就记为2。每次通过时,如果当前的值>=1,就说明不是墙,那么就把当前的值加起来。当然,我们先要初始化一下,把四周的不能走的地方记为0。

    代码如下:

#include<bits/stdc++.h>
using namespace std;

int n,m,k,a[200][200]={0,0},vis[20000]={0},x[1000]={0},y[1000]={0},xx,yy,dx[5]={1,-1,0,0},dy[5]={0,0,1,-1};
char b[200][200]={};

void bfs()
{
	int tail=1,head=1;
	while(tail>=head)
	{
		for(int i=0;i<=3;i++)
		{
			int xxx=x[head]+dx[i],yyy=y[head]+dy[i];
			if(a[xxx][yyy]>=1)
			{
				tail++;
				vis[tail]=vis[head]+a[xxx][yyy];
				a[xxx][yyy]=0;
				x[tail]=xxx;
				y[tail]=yyy;
			}
			if(xxx==xx&&yyy==yy)
			{
			    cout<<vis[tail];
			    return;
			}
		}
		head++;
	}
	cout<<"NO";
}

int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	    for(int j=1;j<=m;j++)
	    {
	    	cin>>b[i][j];
	    	if(b[i][j]=='.')a[i][j]=1;
	    	else if(b[i][j]=='R')a[i][j]=1,x[1]=i,y[1]=j;
	    	else if(b[i][j]=='A')a[i][j]=1,xx=i,yy=j;
	    	else if(b[i][j]=='S')a[i][j]=2;
	    }
	bfs();
	return 0;
} 
    注释就不加了,老师说加注释很麻烦的。。。

    这样就可以过了。


    另外,我们也要来一道深搜的剪枝。就举老师讲得小木棍吧。(欢迎来到乱七八糟忘记题面,所有题目全靠乱编

    这题大概就是把几个数分成几组,要使每组的和最小。(好像也太简略了)
    胡乱分析:
    既然是胡乱分析,也不多说了。这一题暴力的裸搜是非常容易的,最重要的就是剪枝剪枝剪枝!!!这一题我们可以正着剪,倒着剪,甚至还能瞎几把乱剪。但是我非常蒟的,我就只能正着剪,倒着减,优化两个地方,不过会瞎几把乱剪。代码具体就不给了,毕竟体面真的忘了。。。反正剪枝这东西真的非常玄学,一不小心把正确答案剪掉了就GG了。
    学了两天搜索,这一方面的基础应该可以说是有底了,温故而知新可能真的是非常正确的吧。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值