并查集 c++函数的值传递和引用传递 晴神问

目录

学校的班级个数

手推7个班级,答案17?怀疑人生

破案了,应该是6个班。

破案了,原来写的是 unionxy(a, b, father);

c++ if两个数同时为正或为负 简洁写法

可以用位运算?

c++可以这样赋值吗?a=b=2

典型数组越界报错:Line 1122: Char 34: runtime error: addition of unsigned offset to 0x502000000190 overflowed to 0x50200000018c (stl_vector.h) SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/bits/stl_vector.h:1131:34class Solution { public: int search(vector & nums, int target) { int n=nums.size(); int left=-1,right=n-1,x=nums[n-1]; int mid = left+(right-left)/2;int m = nums[mid]; while(left+1 x&&x>=m) right=mid-1;else left=mid;} } return (right =0&&nums[right]==target)?right:-1; } };

修改说明:

解释:

warning: ^ has lower precedence than <; < will be evaluated first [-Wparentheses] 22 | if((p->val-root->val)^(q->val-root->val)<0) | ^~~~~~~~~~~~~~~~~~~~~怎么办

解释:

c++函数传入Vector《int》 在函数里面修改vector可以吗

1. 按值传递(修改不会影响原始向量)

2. 按引用传递(修改会影响原始向量)

3. 按常量引用传递(如果不需要修改向量)

三目


题目

学校的班级个数

通过数

1696

提交数

3677

难度

中等

显示标签


题目描述

现有一个学校,学校中有若干个班级,每个班级中有若干个学生,每个学生只会存在于一个班级中。如果学生A和学生B处于一个班级,学生B和学生C处于一个班级,那么我们称学生A和学生C也处于一个班级。

现已知学校中共n​个学生(编号为从1n),并给出m​组学生关系(指定两个学生处于一个班级),问总共有多少个班级。

输入描述

第一行两个整数n​​、m​​(1≤n≤100,1≤m≤100​​),分别表示学生个数、学生关系个数;

接下来m​行,每行两个整数a​和b​(1≤a≤n,1≤b≤n​, a≠b),表示编号为a的学生和编号为b的学生处于一个班级。

输出描述

输出一个整数,表示班级个数。

样例1

输入

复制

 

5 3 4 2 1 3 2 5

输出

复制

 

2

解释

编号245的学生在同一个班级,编号13的学生在同一个班级,因此共有两个班级。

手推7个班级,答案17?怀疑人生

不服来战?

57 46 22 20 20 46 9 22

41 3030 4 42 48 30 5 41 6 29 5050 4 5 1 49 5 41 48 24 56 23 56 21 8 3 9 24 21 12 21 11 49

31 40 10 31 51 13 10 13

45 52

37 2 15 3737 33 26 27 33 26 55 15 55 2727 38 43 5454 2 54 26 54 36

14 19

44 32

破案了,应该是6个班。

答案17是把没出现的人一人一班。。。

1

57:1

57:3

57:4

57:5

57:6

57:8

57:9

57:11

57:12

57:20

57:21

57:22

57:23

57:24

57:29

57:30

57:41

57:42

57:46

57:48

57:49

57:50

57:56

57:57

7:7

2

13:51

13:10

13:13

13:31

13:40

16:16

17:17

18:18

3

19:19

19:14

25:25

28:28

34:34

4

32:32

32:44

35:35

5

38:26

38:2

38:15

38:27

38:33

38:36

38:37

38:38

38:43

38:54

38:55

39:39

47:47

6

52:45

52:52

53:53

破案了,原来写的是 unionxy(a, b, father);

因为他编号从1开始,你不减一会数组越界 unionxy(a-1, b-1, father);

-1立马完美通过

#include<stdio.h>
#include<bits/stdc++.h>
#include<vector>
using namespace std;vector<int> init(int n)
{vector<int> father(n,1);//父亲都初始化为自己for(int i=0;i<n;i++)father[i]=i;return father;
}
int findFather(int a,vector<int>& father)
{int x=a;//记录该节点while(a!=father[a])a=father[a];int f=father[a];//记录根节点a=x;while(a!=father[a]){int temp = father[a];father[a] = f;a = temp;}//压缩路径return f;
}
void unionxy(int a,int b,vector<int>& father)
{//while(a!=father[a])a=father[a];father[findFather(a,father)]=findFather(b,father);findFather(a,father);
}
int main()
{int n,m,a,b,num=0;//cout<<n<<m;scanf("%d %d",&n,&m);
vector<int> father=init(n);for (int j=0;j<m;j++){scanf("%d %d",&a,&b);unionxy(a-1,b-1,father);}for(int i=0;i<n;i++)if(father[i]==i)num++;printf("%d",num);}

c++ if两个数同时为正或为负 简洁写法

ChatGLM

在C++中,要判断两个数同时为正或同时为负,可以使用逻辑运算符来实现简洁的写法。假设有两个整数变量 a 和 b,可以使用以下代码:

cpp

复制

if ((a > 0 && b > 0) || (a < 0 && b < 0)) {// 两个数同时为正或同时为负
}

这段代码的逻辑是:

  • (a > 0 && b > 0) 检查 a 和 b 是否同时为正。
  • (a < 0 && b < 0) 检查 a 和 b 是否同时为负。
  • || 运算符表示“或”,即只要满足其中一个条件,整个条件就为真。

这样就可以简洁地判断两个数是否同时为正或同时为负。

访客_c53a24

可以用位运算?

ChatGLM

是的,可以使用位运算来简洁地判断两个数是否同时为正或同时为负。这种方法利用了符号位的概念。在大多数计算机系统中,整数的符号位是最高位,正数的符号位为0,负数的符号位为1。

假设有两个整数变量 a 和 b,可以使用以下代码:

c

复制

if (((a ^ b) >= 0)) {// 两个数同时为正或同时为负
}

解释:

  • a ^ b 是按位异或操作。如果 a 和 b 的符号位相同(即同时为正或同时为负),那么 a ^ b 的符号位将为0,整个结果将是一个非负数。
  • 因此,((a ^ b) >= 0) 将在 a 和 b 同时为正或同时为负时为真。

这种方法利用了位运算的特性,避免了显式的条件判断,从而更加简洁高效。

访客_c53a24

c++可以这样赋值吗?a=b=2

ChatGLM

在C++中,你可以使用链式赋值,即连续给多个变量赋相同的值。所以,a = b = 2 是合法的,并且会将 2 赋值给 b,然后再将 b 的值赋给 a

例如:

cpp
int a, b;
a = b = 2;
std::cout << a << " " << b << std::endl; // 输出: 2 2

这行代码的执行顺序如下:

  1. b = 2:将 2 赋值给 b
  2. a = b:将 b 的值(现在是 2)赋值给 a

因此,a 和 b 最终都会被赋值为 2

访客_c53a24

典型数组越界报错:Line 1122: Char 34: runtime error: addition of unsigned offset to 0x502000000190 overflowed to 0x50200000018c (stl_vector.h) SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/bits/stl_vector.h:1131:34class Solution { public: int search(vector<int>& nums, int target) { int n=nums.size(); int left=-1,right=n-1,x=nums[n-1]; int mid = left+(right-left)/2;int m = nums[mid]; while(left+1<right) { mid = left+(right-left)/2; m = nums[mid]; if(target<=m) { if(target==m){right=mid;break;} if(target<=x&&x<m) left= mid-1;else right=mid; }else {if(target>x&&x>=m) right=mid-1;else left=mid;} } return (right<n&&right>=0&&nums[right]==target)?right:-1; } };


你遇到的错误与向量(数组)索引计算时的溢出有关。这通常发生在当你尝试用一个超出有效范围的索引去访问向量中的元素,或者在进行索引相关的算术运算时发生了溢出。

在你的代码里,问题可能出在 mid(中间索引)的计算上,或者 left(左边界)和 right(右边界)这两个索引的维护上。我们来检查一下代码,并进行修改,以确保索引始终在有效的范围内。

下面是修改后的代码版本,包含了一些改进,可以更好地处理索引问题:

cpp

复制

#include <vector>
using namespace std;class Solution {
public:int search(vector<int>& nums, int target) {int n = nums.size();if (n == 0) return -1; // 如果数组为空,直接返回-1int left = 0, right = n - 1; // 初始化左边界为0,右边界为最后一个元素的索引int x = nums[n - 1]; // 获取最后一个元素的值(虽然在这个修正版本里暂时用不到,但保留)while (left <= right) { // 循环条件:只要左边界不越过右边界就继续int mid = left + (right - left) / 2; // 计算中间索引,这样写可以避免整数溢出int m = nums[mid]; // 获取中间位置的元素值if (m == target) {return mid; // 如果中间元素正好是目标值,直接返回它的索引} else if (m < target) {left = mid + 1; // 如果中间元素小于目标值,说明目标在右半部分,调整左边界} else {right = mid - 1; // 如果中间元素大于目标值,说明目标在左半部分,调整右边界}}return -1; // 如果循环结束都没找到,返回-1表示目标不在数组中}
};

修改说明:

  1. 初始检查:增加了一个检查,如果传入的向量是空的(大小为0),直接返回-1,避免后续操作出错。
  2. 初始化:将 left 初始化为0,right 初始化为 n - 1(数组的最后一个有效索引),确保它们一开始就在合法的范围内。
  3. 循环条件:将循环条件改为 left <= right。这意味着只要 left 不大于 right,循环就会继续。当 left 最终等于 right + 1 时,循环结束,表明已经搜索了所有可能的位置。
  4. Mid 计算:计算 mid 的方式改为 left + (right - left) / 2。这种写法比 (left + right) / 2 更安全,因为它先计算 right - left,这个差值通常比 left + right 小得多,不容易溢出,尤其是在 left 和 right 都很大的时候。
  5. 比较逻辑:简化了比较逻辑。直接检查 mid 位置的元素 m 是否等于 target。如果不等于,根据 m 与 target 的大小关系,将搜索范围缩小到左半部分或右半部分。

这个修改后的代码版本应该能正确处理索引,避免你之前遇到的溢出问题。如果你的问题依然存在,请提供更多的上下文信息或者具体的错误信息,我会尽力提供进一步的帮助。

访客_c53a24

/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { auto dfs=[&](this auto&& dfs,TreeNode* root)-> TreeNode* { if(root==q||root==q||root==NULL)return root; TreeNode* l = dfs(root->left); TreeNode* r = dfs(root->right); if(l!=NULL&&r!=NULL)return root;else return (l!=NULL)? l: r; }; return dfs(root); } };哪里有错

ChatGLM

你的代码有几个小错误和可以改进的地方:

  1. 在 if(root==q||root==q||root==NULL) 这一行中,root==q 出现了两次,应该是 root==p 和 root==q

  2. 在 if(l!=NULL&&r!=NULL)return root;else return (l!=NULL)? l: r; 这一行中,逻辑可以简化,因为如果 l 和 r 都不为 NULL,那么 root 就是最低公共祖先。否则,返回 l 或 r 中不为 NULL 的那个。

以下是修正后的代码:

cpp

复制

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/
class Solution {
public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {auto dfs = [&](this auto&& dfs, TreeNode* root) -> TreeNode* {if (root == nullptr) return nullptr;if (root == p || root == q) return root;TreeNode* left = dfs(root->left);TreeNode* right = dfs(root->right);if (left != nullptr && right != nullptr) return root;return left != nullptr ? left : right;};return dfs(root);}
};

解释:

  1. 初始检查:如果 root 是 nullptr,直接返回 nullptr
  2. 找到目标节点:如果 root 是 p 或 q,返回 root
  3. 递归搜索:递归搜索左子树和右子树。
  4. 确定最低公共祖先
    • 如果左子树和右子树都找到了目标节点,那么当前节点就是最低公共祖先。
    • 否则,返回左子树或右子树中找到的目标节点。

这样修改后,代码逻辑更加清晰,并且能够正确找到最低公共祖先。

访客_c53a24

 if((p->val-root->val)^(q->val-root->val)<0)

warning: ^ has lower precedence than <; < will be evaluated first [-Wparentheses] 22 | if((p->val-root->val)^(q->val-root->val)<0) | ^~~~~~~~~~~~~~~~~~~~~怎么办

ChatGLM

这个警告是因为 ^(按位异或)运算符的优先级低于 <(小于)运算符。为了避免这种歧义,应该使用括号明确表达式的优先级。

在你的代码中,(p->val - root->val) ^ (q->val - root->val) < 0 这一行,应该明确 (p->val - root->val) 和 (q->val - root->val) 的异或操作优先于 < 操作。

以下是修正后的代码:

cpp
if (((p->val - root->val) ^ (q->val - root->val)) < 0)
// 你的代码逻辑

;

解释:

  1. 使用额外的括号 ((p->val - root->val) ^ (q->val - root->val)) 来确保异或操作优先于比较操作。
  2. 这样可以避免优先级问题,并且代码更加清晰。

这样修改后,编译器就不会再发出警告,并且代码的逻辑也更加明确。

访客_c53a24

c++函数传入Vector《int》 在函数里面修改vector可以吗

ChatGLM

是的,在C++中,你可以将一个 std::vector<int> 传递给函数,并在函数内部修改它。默认情况下,如果你直接传递 std::vector<int>,它是按值传递的,这意味着函数内部会创建一个该向量的副本,对副本的修改不会影响原始向量。

如果你想在函数内部修改原始向量,你可以使用引用传递。以下是两种方法:

1. 按值传递(修改不会影响原始向量)

cpp

复制

#include <vector>
#include <iostream>void modifyVector(std::vector<int> vec) {vec.push_back(4); // 修改的是副本
}int main() {std::vector<int> myVector = {1, 2, 3};modifyVector(myVector);// myVector 仍然是 {1, 2, 3}for (int num : myVector) {std::cout << num << " ";}return 0;
}

2. 按引用传递(修改会影响原始向量)

cpp

复制

#include <vector>
#include <iostream>void modifyVector(std::vector<int>& vec) {vec.push_back(4); // 修改的是原始向量
}int main() {std::vector<int> myVector = {1, 2, 3};modifyVector(myVector);// myVector 现在是 {1, 2, 3, 4}for (int num : myVector) {std::cout << num << " ";}return 0;
}

3. 按常量引用传递(如果不需要修改向量)

如果你只是想在函数内部读取向量,而不需要修改它,可以使用常量引用传递:

cpp

复制

#include <vector>
#include <iostream>void printVector(const std::vector<int>& vec) {for (int num : vec) {std::cout << num << " ";}std::cout << std::endl;
}int main() {std::vector<int> myVector = {1, 2, 3};printVector(myVector);// myVector 仍然是 {1, 2, 3}return 0;
}

引用

总结:

  • 按值传递:函数内部修改的是副本,不影响原始向量。
  • 按引用传递:函数内部修改的是原始向量。
  • 按常量引用传递:函数内部只能读取向量,不能修改。

根据你的需求选择合适的方式传递向量。

三目

偶会报错

cout << (findFather(k, father) == findFather(j, father)) ? "Yes" : "No" << endl;

解决方法是加个括号 

cout << ((findFather(k, father) == findFather(j, father)) ? "Yes" : "No" )<< endl;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/bicheng/82882.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt Creator快捷键合集

前言 QtCreator是一款跨平台的IDE,专为Qt开发设计,支持C/C++/JS/Python编程,支持设备远程调试,支持代码高亮,集成帮助文档,原生支持cmake和git,确实是一款朴实而又强大的集成开发环境,让人有种爱不释手的感觉 编辑 功能快捷键复制Ctrl + C粘贴Ctrl + V剪切Ctrl + X代…

docker网络相关内容详解

一、docker与k8s 一、Docker 核心解析 1. Docker 定义与架构 本质&#xff1a; 容器化平台&#xff08;构建容器化应用&#xff09;、进程管理软件&#xff08;守护进程管理容器生命周期&#xff09;。客户端&#xff08;docker cli&#xff09;与服务端&#xff08;docker ser…

首发!PPIO派欧云上线DeepSeek-R1-0528-Qwen3-8B蒸馏模型

首发&#xff01;PPIO派欧云上线DeepSeek-R1-0528-Qwen3-8B蒸馏模型 DeepSeek R1 系列的模型更新还在继续。 继昨天 PPIO派欧云首发上线 DeepSeek-R1-0528 模型后&#xff0c;今天 PPIO 再次首发 DeepSeek 最新开源的蒸馏模型 DeepSeek-R1-0528-Qwen3-8B。 DeepSeek-R1-0528-Q…

如何用命令行将 PDF 表格转换为 HTML 表格

本文将介绍如何使用命令行将可填写的 PDF 表单转换为 HTML 表单。只需几行代码即可完成转换。将可填写的 PDF 表单转换为 HTML 表单后&#xff0c;你可以在网页上显示这些表单。本指南使用 FormVu 来演示转换过程。 使用命令行将可填写 PDF 表单转换为 HTML 表单 你可以通过命…

杰发科技AC7840——CSE硬件加密模块使用(2)

注意&#xff1a; 不要随便修改主秘钥&#xff0c;本次跑代码过程中&#xff0c;对主秘钥进行修改&#xff0c;导致无法对cse模块恢复出厂设置 更新秘钥例程 第2个例程主要是把cse的key加载到cse安全区域中 这里刚看到加载秘钥并不是直接把明文加载到cse模块 测试第3个例程 复…

浅解Vue 数据可视化开发建议与速度优化

数据可视化在现代前端应用中至关重要&#xff0c;但处理大规模数据时容易遇到性能瓶颈。以下是针对 Vue 项目的个人看法的优化方案&#xff1a; 文章目录 一、框架选型建议二、大数据渲染优化三、渲染性能提升四、内存管理五、监控与调试六、进阶优化方案七、Vue特定优化八、构…

lua脚本学习笔记1:Vscode添加lua环境_lua基本语法

下载Lua环境&#xff0c;lua语言基本语法。 目录 lua介绍&#xff1a; VsCode添加Lua编程环境 下载Lua 配置环境变量 查询lua环境 打开 VSCode&#xff0c;安装 Lua 语言插件和调试器 VScode增添lua编译器路径 测试lua程序&#xff1a; 代码&#xff1a; 结果&#xff1a; 参考…

Nordic nRF52832使用寄存器实现SPI功能

目录 概述 1 SPI相关的寄存器 1.1 SPI的框架结构 1.2 功能描述 1.3 SPI Master模式引脚配置 1.4 SPI Master模式下的时序 2 SPI相关的寄存器 2.1 Instances 2.2 详细寄存器定义 2.3 SPI master interface特性 3 Zephyr 平台下SPI功能时序&#xff08;寄存器&#xf…

【Python办公】将Excel表格转json(字典)数据-可自定义key和value

目录 专栏导读背景介绍库的安装数据源准备代码1:key1列,value所有列代码1:key多列,value所有列代码3:key自选,value自选总结专栏导读 🌸 欢迎来到Python办公自动化专栏—Python处理办公问题,解放您的双手 🏳️‍🌈 博客主页:请点击——> 一晌小贪欢的博客主页求关…

DexWild:野外机器人策略的灵巧人机交互

25年5月来自 CMU 的论文“DexWild: Dexterous Human Interactions for In-the-Wild Robot Policies”。 大规模、多样化的机器人数据集已成为将灵巧操作策略泛化到新环境的一条有效途径&#xff0c;但获取此类数据集面临诸多挑战。虽然遥操作可以提供高保真度的数据集&#xf…

[蓝帽杯 2022 初赛]网站取证_2

一、找到与数据库有关系的PHP文件 打开内容如下&#xff0c;发现数据库密码是函数my_encrypt()返回的结果。 二、在文件夹encrypt中找到encrypt.php,内容如下&#xff0c;其中mcrypt已不再使用&#xff0c;所以使用php>7版本可能没有执行结果&#xff0c;需要换成较低版本…

星海掘金:校园极客的Token诗篇(蓝耘MaaS平台)——从数据尘埃到智能生命的炼金秘录

hi&#xff0c;我是云边有个稻草人 目录 前言 一、初识蓝耘元生代MaaS平台&#xff1a;零门槛体验AI服务 1.1 从零开始——平台注册与环境搭建 1.2 平台核心功能 1.3 蓝耘平台的优势在哪里&#xff1f; 二、知识库构建新篇章&#xff1a;从零碎资料到智能语义仓库的蜕变…

nt!MmMapViewInSystemCache函数分析PointerPte的填充

第一部分&#xff1a; 1: kd> kc # 00 nt!MmMapViewInSystemCache 01 nt!CcGetVacbMiss 02 nt!CcGetVirtualAddress 03 nt!CcMapData 04 Ntfs!NtfsMapStream 05 Ntfs!NtfsReadBootSector 06 Ntfs!NtfsMountVolume 07 Ntfs!NtfsCommonFileSystemControl 08 Ntfs!NtfsFspDis…

Tailwind CSS 实战,基于Kooboo构建AI对话框页面(一)

在当今数字化时代&#xff0c;AI 助手已成为网站和应用不可或缺的一部分。本文将带你一步步使用 Tailwind CSS 和 Kooboo 构建一个现代化的 AI 对话界面框。 一、选择 Kooboo平台 的核心优势 智能提示&#xff1a;在输入 class 属性时&#xff0c;会自动触发 Tailwind CSS 规则…

【JavaEE】-- 网络原理

文章目录 1. 网络发展史1.1 广域网1.2 局域网 2. 网络通信基础2.1 IP地址2.2 端口号2.3 认识协议2.4 五元组2.5 协议分层2.5.1 分层的作用2.5.2 OSI七层模型&#xff08;教科书&#xff09;2.5.3 TCP/IP五层&#xff08;或四层&#xff09;模型&#xff08;工业中常用&#xff…

UVa1384/LA3700 Interesting Yang Hui Triangle

UVa1384/LA3700 Interesting Yang Hui Triangle 题目链接题意分析AC 代码 题目链接 本题是2006年icpc亚洲区域赛上海赛区的题目 题意 给出素数P和整数N&#xff0c;求杨辉三角第N1行中不能整除P的数有几个&#xff0c; P < 1000 , N ≤ 10 9 P<1000,\;N≤10^9 P<1000…

文件系统与文件管理:从磁盘到内核的全链路解析

一、文件系统&#xff1a;磁盘的 “数据管家” 1.1 硬盘物理结构&#xff1a;数据存储的硬件基础 硬盘如同一个多层书架&#xff0c;由以下核心部件构成&#xff1a; 盘片&#xff1a;多层磁性圆盘&#xff0c;正反两面覆盖磁性涂层&#xff0c;用于存储二进制数据&#xff…

HTML5 Canvas 星空战机游戏开发全解析

HTML5 Canvas 星空战机游戏开发全解析 一、游戏介绍 这是一款基于HTML5 Canvas开发的2D射击游戏&#xff0c;具有以下特色功能&#xff1a; &#x1f680; 纯代码绘制的星空动态背景✈️ 三种不同特性的敌人类型&#x1f3ae; 键盘控制的玩家战机&#x1f4ca; 完整的分数统…

Telegram平台分发其聊天机器人Grok

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

【GlobalMapper精品教程】095:如何获取无人机照片的拍摄方位角

文章目录 一、加载无人机照片二、计算方位角三、Globalmapper符号化显示方向四、arcgis符号化显示方向一、加载无人机照片 打开软件,加载无人机照片,在GLobalmapperV26中文版中,默认显示如下的航线信息。 关于航线的起止问题,可以直接从照片名称来确定。 二、计算方位角 …