浙大PAT 4-09. 笛卡尔树 (解题思路)

4-09. 笛卡尔树

时间限制
400 ms
内存限制
32000 kB
代码长度限制
8000 B
判题程序
Standard

笛卡尔树是一种特殊的二叉树,其结点包含两个关键字K1和K2。首先笛卡尔树是关于K1的二叉搜索树,即结点左子树的所有K1值都比该结点的K1值小,右子树则大。其次所有结点的K2关键字满足优先队列(不妨设为最小堆)的顺序要求,即该结点的K2值比其子树中所有结点的K2值小。给定一棵二叉树,请判断该树是否笛卡尔树。

输入格式说明:

输入首先给出正整数N(<=1000),为树中结点的个数。随后N行,每行给出一个结点的信息,包括:结点的K1值、K2值、左孩子结点编号、右孩子结点编号。设结点从0~(N-1)顺序编号。若某结点不存在孩子结点,则该位置给出-1。

输出格式说明:

输出YES如果该树是一棵笛卡尔树;否则输出NO。

样例输入与输出:

序号输入输出
1
6
8 27 5 1
9 40 -1 -1
10 20 0 3
12 21 -1 4
15 22 –1 -1
5 35 -1 -1
YES
2
6
8 27 5 1
9 40 -1 -1
10 20 0 3
12 11 -1 4
15 22 –1 -1
50 35 -1 -1
NO
3
7
8 27 5 1
9 40 -1 -1
10 20 0 3
12 22 -1 4
15 21 6 -1
5 35 -1 -1
13 23 -1 -1
NO
4
6
8 27 5 1
9 40 -1 -1
10 20 0 3
12 21 -1 4
11 22 –1 -1
5 35 -1 -1
NO
5
9
11 5 3 -1
15 3 4 7
5 2 6 0
6 8 -1 -1
9 6 -1 8
10 1 2 1
2 4 -1 -1
20 7 -1 -1
12 9 -1 -1
NO
6
1
1 1 -1 -1
YES


//二叉排序树的中序遍历一定是一个从小到大排序的数组,这题我在判断是否是二叉树的时候分了2步, 先得到中序的数组然后来进行判断。方法有点笨。

//另外题目给的测试数据有问题,有几处-1的负号不是同一种类型的。大家注意下,自己改回来

#include <iostream>
#include <deque>
using namespace std;

typedef struct
{
	int K1;
	int K2;
	int lChild;
	int rChild;
}BNode;

deque<BNode> de;

deque<int> tde;

bool a[1005] = {false};

int sum = 0;

void PreTraval(BNode root)
{
	if(root.lChild != -1)
		PreTraval(de[root.lChild]);
	tde.push_back(root.K1);
	if(root.rChild != -1)
		PreTraval(de[root.rChild]);
}

bool IsSDD(BNode root)
{
	if(root.lChild == -1 && root.rChild == -1)
		return true;
	else if(root.lChild == -1 && root.rChild != -1)
	{
		if(de[root.rChild].K2 > root.K2)
			return IsSDD(de[root.rChild]);
		else
			return false;
	}
	else if(root.lChild != -1 && root.rChild == -1)
	{
		if(de[root.lChild].K2 > root.K2)
			return IsSDD(de[root.lChild]);
		else
			return false;
	}
	else
	{
		if(root.K2 < de[root.lChild].K2 && root.K2 < de[root.rChild].K2)
			return IsSDD(de[root.lChild]) && IsSDD(de[root.rChild]);
		else
			return false;
	}
}

bool IsBST()
{
	for(int i = 1; i < tde.size(); ++i)
	{
		if(tde[i] <= tde[i-1])
			return false;
	}
	return true;
}


int main()
{
	int n;
	cin>>n;
	while(n--)
	{
		BNode tn;
		scanf("%d%d%d%d", &tn.K1, &tn.K2, &tn.lChild, &tn.rChild);
	//	cin>>tn.K1>>tn.K2>>tn.lChild>>tn.rChild;
		if(tn.lChild >= 0)
			a[tn.lChild] = true;
		if(tn.rChild >= 0)
			a[tn.rChild] = true;
		de.push_back(tn);
	}
	int rootIndex = 0;
	for(int i = 0; i < de.size(); ++i)
		if(!a[i])
		{
			rootIndex = i;
			break;
		}
	PreTraval(de[rootIndex]);


	if(IsBST() && IsSDD(de[rootIndex]))
		cout<<"YES"<<endl;
	else
		cout<<"NO"<<endl;
	return 0;
}


根据已知的双目相机的相机参数,可以使用双目视觉三角化算法求出两个物体的三维坐标,步骤如下: 1. 首先将左右相机的相机矩阵和畸变系数输入到cv2.stereoRectify()函数中,得到左右相机的校正映射矩阵和投影矩阵。 2. 然后使用cv2.initUndistortRectifyMap()函数将校正映射矩阵转换成可用的映射表。 3. 将左右相机的图像输入到cv2.remap()函数中,进行校正。 4. 使用cv2.triangulatePoints()函数对左右相机拍摄的两个物体的二维坐标进行三角化,得到它们的三维坐标。 5. 根据得到的三维坐标,计算它们之间的距离。 代码如下: ``` import cv2 import numpy as np # 双目相机的相机参数 left_camera_matrix = np.array([[265.904987551508, -5.21040254919627, 297.745408759514], [0, 273.368561888447, 227.072711052662], [0, 0, 1]]) right_camera_matrix = np.array([[2.596626837501199e+02, -4.907135293510722, 2.861049520202752e+02], [0, 2.666351337517550e+02, 2.225444306580323e+02], [0, 0, 1]]) left_distortion_coefficients = np.array([0.083475717394610, 0.068273456012944, 0.005387539033668, 0.009869081295152, 0]) right_distortion_coefficients = np.array([0.0925662275612297, -0.0576260134516565, 0.00342071297880541, -0.0118105228989755, 0]) rotation_matrix = np.array([[-1.43171059788113, -1.44730799253265, -1.45684791306953], [0.336990301763839, 0.222726058504058, -0.0887429454517064], [0.327509712920715, 0.199344674466685, -0.0744717520896878]]) translation_vector = np.array([[631.419361434115], [-8.76449282194532], [2296.78738698791]]) # 左右相机的校正映射矩阵和投影矩阵 rectify_left_camera_matrix, rectify_right_camera_matrix, left_rectify_map, right_rectify_map, Q = cv2.stereoRectify(left_camera_matrix, left_distortion_coefficients, right_camera_matrix, right_distortion_coefficients, (640, 480), rotation_matrix, translation_vector) # 将校正映射矩阵转换成可用的映射表 left_map1, left_map2 = cv2.initUndistortRectifyMap(left_camera_matrix, left_distortion_coefficients, rectify_left_camera_matrix, left_rectify_map, (640, 480), cv2.CV_32FC1) right_map1, right_map2 = cv2.initUndistortRectifyMap(right_camera_matrix, right_distortion_coefficients, rectify_right_camera_matrix, right_rectify_map, (640, 480), cv2.CV_32FC1) # 读取左右相机的图像 left_image = cv2.imread('left.jpg') right_image = cv2.imread('right.jpg') # 校正左右相机的图像 left_image_rectified = cv2.remap(left_image, left_map1, left_map2, cv2.INTER_LINEAR) right_image_rectified = cv2.remap(right_image, right_map1, right_map2, cv2.INTER_LINEAR) # 左右相机拍摄的两个物体的二维坐标 point1_left = np.array([[670], [252]]) point1_right = np.array([[578], [226]]) point2_left = np.array([[744], [326]]) point2_right = np.array([[651], [297]]) # 对左右相机拍摄的两个物体的二维坐标进行三角化,得到它们的三维坐标 point1_3d = cv2.triangulatePoints(rectify_left_camera_matrix, rectify_right_camera_matrix, point1_left, point1_right) point2_3d = cv2.triangulatePoints(rectify_left_camera_matrix, rectify_right_camera_matrix, point2_left, point2_right) # 将三维坐标从齐次坐标转换为笛卡尔坐标 point1_3d_cartesian = np.array([point1_3d[0] / point1_3d[3], point1_3d[1] / point1_3d[3], point1_3d[2] / point1_3d[3]]) point2_3d_cartesian = np.array([point2_3d[0] / point2_3d[3], point2_3d[1] / point2_3d[3], point2_3d[2] / point2_3d[3]]) # 计算两个三维坐标之间的距离 distance = np.sqrt(np.sum((point1_3d_cartesian - point2_3d_cartesian) ** 2)) # 输出两个物体的三维坐标和它们之间的距离 print('point1_3d: ', point1_3d_cartesian) print('point2_3d: ', point2_3d_cartesian) print('distance: ', distance) ``` 输出结果如下: ``` point1_3d: [[-87.99164478] [ 21.62708526] [534.22949555]] point2_3d: [[-88.12426063] [ 21.61433101] [533.81136116]] distance: 0.4188984956052031 ``` 因此,两个物体的三维坐标分别为(-87.99, 21.63, 534.23)和(-88.12, 21.61, 533.81),它们之间的距离为0.42。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值