PAT 1143

BST(二叉搜索树)与其先序遍历(preorder traversal sequence ),即先序遍历中每个点都可以看做是所在子树的根结点。而本题需要求出两个点的lca问题。根据BST的性质与先序遍历,可直接进行暴力,得到结果。
顺便在这里回顾一下以前的知识,BST的中序遍历就是BST中各结点从小到大排列好的结果。

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int pre[N];
map<int, bool> pos;

int main()
{
    int m, n;
    scanf("%d%d", &m, &n);
    for(int i=1; i<=n; i++){
    	scanf("%d", &pre[i]);
    	pos[pre[i]]=true;
    }

    int a, b;
    while(m--){
    	scanf("%d%d", &a, &b);
    	if(!pos[a] && !pos[b]){
    		printf("ERROR: %d and %d are not found.\n", a, b);
    	} else if(!pos[a] || !pos[b]){
    		printf("ERROR: %d is not found.\n", !pos[a] ? a : b);
    	} else {
    		int res;
    		for(int i=1; i<=n; i++){
    			if((pre[i]<a && pre[i]>b) || (pre[i]>a && pre[i]<b) || (pre[i]==a) || (pre[i]==b)){
    				res=pre[i];
    				break;
    			}
    		}

    		if(res==a || res==b){
    			printf("%d is an ancestor of %d.\n", res==a ? a : b, res==a ? b : a);
    		} else {
    			printf("LCA of %d and %d is %d.\n", a, b, res);
    		}
    	}
    }
	return 0;
}

在这里贴一份,很久以前看别人的代码,虽然不如上面的好

#include <bits/stdc++.h>
using namespace std;
const int N=1e4+10;
int pre[N];
map<int, int> pos;

void lca(int root, int a, int b){
	if(pre[root]>a && pre[root]>b){
		lca(root+1, a, b);
	} else if((pre[root]<a && pre[root]>b) || (pre[root]>a && pre[root]<b)){
		printf("LCA of %d and %d is %d.\n", a, b, pre[root]);
	} else if(pos[pre[root]]<pos[a] && pos[pre[root]]<pos[b]){
		int temp=root;
		while(pre[temp]<=pre[root])
			temp++;

		lca(temp, a, b);
	} else if(a==pre[root]){
		printf("%d is an ancestor of %d.\n", a, b);
	} else if(b==pre[root]){
		printf("%d is an ancestor of %d.\n", b, a);
	}
}

int main()
{
	int m, n;
	scanf("%d%d", &m, &n);
	for(int i=1; i<=n; i++){
		scanf("%d", &pre[i]);
		pos[pre[i]]=i;
	}

	int a, b;
	for(int i=1; i<=m; i++){
		scanf("%d%d", &a, &b);
		if(pos[a] && !pos[b]){
			printf("ERROR: %d is not found.\n", b);
		} else if(!pos[a] && pos[b]){
			printf("ERROR: %d is not found.\n", a);
		} else if(!pos[a] && !pos[b]){
			printf("ERROR: %d and %d are not found.\n", a, b);
		} else {
			lca(1, a, b);
		}
	}

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值