浙大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步, 先得到中序的数组然后来进行判断。方法有点笨。
//二叉搜索树如果直接用递归判断左右是否满足大小关系,则可能会出错,正确的方法是中序遍历判断是否是一个有序数组。

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include <iostream>  
  2. #include <deque>  
  3. using namespace std;  
  4.   
  5. typedef struct  
  6. {  
  7.     int K1;  
  8.     int K2;  
  9.     int lChild;  
  10.     int rChild;  
  11. }BNode;  
  12.   
  13. deque<BNode> de;  
  14.   
  15. deque<int> tde;  
  16.   
  17. bool a[1005] = {false};  
  18.   
  19. int sum = 0;  
  20.   
  21. void PreTraval(BNode root)  
  22. {  
  23.     if(root.lChild != -1)  
  24.         PreTraval(de[root.lChild]);  
  25.     tde.push_back(root.K1);  
  26.     if(root.rChild != -1)  
  27.         PreTraval(de[root.rChild]);  
  28. }  
  29.   
  30. bool IsSDD(BNode root)  
  31. {  
  32.     if(root.lChild == -1 && root.rChild == -1)  
  33.         return true;  
  34.     else if(root.lChild == -1 && root.rChild != -1)  
  35.     {  
  36.         if(de[root.rChild].K2 > root.K2)  
  37.             return IsSDD(de[root.rChild]);  
  38.         else  
  39.             return false;  
  40.     }  
  41.     else if(root.lChild != -1 && root.rChild == -1)  
  42.     {  
  43.         if(de[root.lChild].K2 > root.K2)  
  44.             return IsSDD(de[root.lChild]);  
  45.         else  
  46.             return false;  
  47.     }  
  48.     else  
  49.     {  
  50.         if(root.K2 < de[root.lChild].K2 && root.K2 < de[root.rChild].K2)  
  51.             return IsSDD(de[root.lChild]) && IsSDD(de[root.rChild]);  
  52.         else  
  53.             return false;  
  54.     }  
  55. }  
  56.   
  57. bool IsBST()  
  58. {  
  59.     for(int i = 1; i < tde.size(); ++i)  
  60.     {  
  61.         if(tde[i] <= tde[i-1])  
  62.             return false;  
  63.     }  
  64.     return true;  
  65. }  
  66.   
  67.   
  68. int main()  
  69. {  
  70.     int n;  
  71.     cin>>n;  
  72.     while(n--)  
  73.     {  
  74.         BNode tn;  
  75.         scanf("%d%d%d%d", &tn.K1, &tn.K2, &tn.lChild, &tn.rChild);  
  76.     //  cin>>tn.K1>>tn.K2>>tn.lChild>>tn.rChild;  
  77.         if(tn.lChild >= 0)  
  78.             a[tn.lChild] = true;  
  79.         if(tn.rChild >= 0)  
  80.             a[tn.rChild] = true;  
  81.         de.push_back(tn);  
  82.     }  
  83.     int rootIndex = 0;  
  84.     for(int i = 0; i < de.size(); ++i)  
  85.         if(!a[i])  
  86.         {  
  87.             rootIndex = i;  
  88.             break;  
  89.         }  
  90.     PreTraval(de[rootIndex]);  
  91.   
  92.   
  93.     if(IsBST() && IsSDD(de[rootIndex]))  
  94.         cout<<"YES"<<endl;  
  95.     else  
  96.         cout<<"NO"<<endl;  
  97.     return 0;  
  98. }  
根据已知的双目相机的相机参数,可以使用双目视觉三角化算法求出两个物体的三维坐标,步骤如下: 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、付费专栏及课程。

余额充值