ZOJ 3805 Machine(二叉树,递归)

题意:一颗二叉树,求  “  宽度  ”

思路:递归,貌似这个思路是对的,先记下,但是提交时超时,

1.如果当前节点只有左孩子,那么当前宽度等于左孩子宽度

2.如果当前节点只有右孩子,那么当前宽度等于右孩子宽度

3.如果当前节点既有左孩子又有孩子

    3.1两个孩子宽度相等,则当前宽度等于其中一个孩子宽度+1

    3.2两个孩子宽度不等,则当前宽度等于两个孩子宽度中大的那一个


代码1:超时

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

int tree[10010][2];
int sum;
int dfs(int i){
	if(tree[i][0]==0&&tree[i][1]==0) return 1;
	if(tree[i][0]&&!tree[i][1]) return sum=dfs(tree[i][0]);//只有左孩子
	if(!tree[i][0]&&tree[i][1]) return sum=dfs(tree[i][1]);//只有右孩子
	else 
		if(dfs(tree[i][0])==dfs(tree[i][1])) return sum=dfs(tree[i][0])+1;//相等的时候,宽度为其中一个+1
		else return sum=dfs(tree[i][0])>dfs(tree[i][1])?dfs(tree[i][0]):dfs(tree[i][1]);//不等的时候,宽度为大的
}
int main(){
	int n;
	int i;
	int q;
	while(~scanf("%d",&n)){
		sum=0;
		memset(tree,0,sizeof(tree));
		for(i=2;i<=n;i++){
			scanf("%d",&q);
			if(tree[q][0]==0) tree[q][0]=i;
			else tree[q][1]=i;
		}
		int ans=dfs(1);
		printf("%d\n",ans);
	}
	return 0;
}


代码2:正确,代码1的超时原因是,在递归过程中,递归运算太多了,多了不少重复的运算

但是,以下正确代码更是蛋疼,有两个变量不能定义为全局变量,,,,啊啊啊啊啊,为啥啊,,,

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

int tree[10010][2];
//int lsum,rsum;
int dfs(int i){
	int lsum,rsum;//无语,,这俩变量定义为全局就不对,,求解脱
	if(tree[i][0]==0&&tree[i][1]==0) return 1;
	if(tree[i][0]&&!tree[i][1]){
	//	cout<<"1只有左孩子"<<endl;
        return dfs(tree[i][0]);//只有左孩子
	}
	if(!tree[i][0]&&tree[i][1]){//此处代码不会运行,因为不存在只有右孩子的情况
	//	cout<<"2只有右孩子"<<endl;
        return dfs(tree[i][1]);//只有右孩子
	}
	
	lsum=dfs(tree[i][0]);
	rsum=dfs(tree[i][1]);
	//cout<<"lsum  "<<lsum<<"  rsum   "<<rsum<<endl;
    if(lsum==rsum) {
       // cout<<"3左右孩子相等"<<endl;
       // cout<<"lsum+1   "<<lsum+1<<endl;
        return lsum+1;//相等的时候,宽度为其中一个+1
    }
    else {
       // cout<<"4左右孩子不相等"<<endl;
        return lsum>rsum?lsum:rsum;//不等的时候,宽度为大的
    }
}
int main(){
	int n;
	int i;
	int q;
	while(~scanf("%d",&n)){
		memset(tree,0,sizeof(tree));
		for(i=2;i<=n;i++){
			scanf("%d",&q);
			if(tree[q][0]==0) tree[q][0]=i;
			else tree[q][1]=i;
		}
		int ans=dfs(1);
		printf("%d\n",ans);
	}
	return 0;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值