洛谷P1229/czos 1432/洛谷1030

惭愧啊…今天补n天之前的题…
1.P1229 遍历问题
在这里插入图片描述
题解:已知二叉树前序和中序可以得到后序,已知前序中序也可以得到后序,但是已知前序后序得到的中序是不唯一的,比如说
前序是ab后序是ba,可以确定a是根结点,如果b是a的左子树,前序:ab 后序:ba,如果b是a的右子树,前序:ab ,后序:b,a,所以中序不唯一的原因就在这儿,无法确定父亲结点的左右子树
再比如说前序是DEF,后序是EFD,根结点为D,但这时候的中序序列是确定的,D的左子树为必E,右子树为必F,为什么这时候的左右子树可以确定呢?因为父亲结点D它有左右两个儿子,在这个情况下,后序遍历顺序是左->右->根,所以这时候的左右子树可以唯一确定下来。所以我们只要找到只有一个儿子的结点的个数然后就好办了
类似于前序是ab,后序是ba的就是只有一个儿子结点的结点,可以这样理解,如果结点a不是只有一个儿子结点,就是说它有左右两个儿子结点,那它的后序序列b后面肯定不能直接跟父亲结点a,跟的肯定是右儿子
AC代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
   string a,b;
   cin>>a>>b;
   int len=a.size();
   int ans=0;
   for(int i=0;i<=len-1;i++)
   {
   	for(int j=0;j<=len-1;j++)
   	{
	   	   if(a[i]==b[j]&&a[i+1]==b[j-1]&&i+1<=len-1&&j-1>=0)
			  {
			  	//cout<<i<<" "<<j<<endl;
			  	ans++;
			  }
	}
   }
   //cout<<ans<<endl;
     int temp=1<<ans;
     cout<<temp<<endl;

}
/*样例中
前:abc
后:cba  只有一个儿子结点的是a和b
可以简单推算到
a[0]=b[2]   a[1]=b[1]
a[1]=b[1]   a[3]=b[0]
这时候
a[i]==b[j]&&a[i+1]==b[j-1] 
*/

2.求走出迷宫的最小步数
题目大意:一个迷宫,有的格子里有障碍物,不能走;有的格子是空地,可以走。
给定一个迷宫,求从左上角走到右下角最少需要走多少步,只能上下左右走
题解:dfs+回溯,主要是要能自己模拟出回溯的过程,这很重要,区分递归回上一层和回退到上一层有什么区别

#include<bits/stdc++.h>
using namespace std;
int m,n;
char a[50][50];
int d[50][50];//存储到每个点至少需要多少步 
int fx[5]={0,0,1,0,-1};
int fy[5]={0,1,0,-1,0};
//递归探索地图,求到每个点至少需要多少步 
void dfs(int x,int y,int step)
{
	d[x][y]=step;
	int tx,ty;
	for(int i=1;i<=4;i++)
	{
		tx=x+fx[i];
		ty=y+fy[i];
		//如果tx,ty可以探索(该点可以探索且走到该点的步数更少) 
		if(a[tx][ty]=='.'&&step+1<d[tx][ty])
		dfs(tx,ty,step+1);
	}	 
}
int main()
{	
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cin>>a[i][j];
			d[i][j]=99999999;
		}
	}
	dfs(1,1,1);	
	cout<<d[n][m]<<endl;
}

洛谷 1030
在这里插入图片描述
题解:已知中序后序求先序,先找出后序结点在中序序列中的位置,然后找出中序后序左右子树的端点递归即可,其实重要的是找出这个递归模型和递归出口,我一开始做这题,模拟电脑去深究它里面的每一步,然后给自己绕晕了。
感谢李同学对我这类题型的倾情指导!
在这里插入图片描述
AC代码:

#include<bits/stdc++.h>
using namespace std;
string a,b;
int k;
int find(char s)
{
	for(int i=0;i<a.size();i++)
	{
		if(a[i]==s)
		{
			k=i;
			break;
		}
	}
	return k;
}
void qianxu(int x,int y,int p,int q)//中序,后序 
{   if(x>y||p>q)
      return;
   //找出后序结点在中序序列中的位置
   int m=find(b[q]);
   cout<<a[m];
   //左子树 
   qianxu(x,m-1,p,q-y+m-1);
   //右子树 
   qianxu(m+1,y,q-y+m,q-1);   
}
int main()
{
	cin>>a>>b;//中 后 
	int len=a.size()-1;
	qianxu(0,len,0,len);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值