题解:洛谷 P1888 三角函数
【题目来源】
【题目描述】
输入一组勾股数 \(a,b,c(a\neq b\neq c)\),用分数格式输出其较小锐角的正弦值。(要求约分。)
【输入】
一行,包含三个正整数,即勾股数 \(a,b,c\)(无大小顺序)。
【输出】
一行,包含一个分数,即较小锐角的正弦值
【输入样例】
3 5 4
【输出样例】
3/5
【核心思想】
-
问题分析:给定一组勾股数 \(a, b, c\)(无大小顺序),要求输出较小锐角的正弦值(约分后的最简分数)。在直角三角形中,较小锐角对应较短的直角边,其正弦值 = 对边(最短直角边)/ 斜边(最长边,即 \(c\))。
-
算法选择:
- 排序确定边:将三数排序后,\(a[0]\) 为最短直角边(较小锐角的对边),\(a[2]\) 为斜边
- 欧几里得算法求 GCD:计算分子分母的最大公约数进行约分
-
关键步骤:
- 读入数据:
cin >> a[0] >> a[1] >> a[2] - 排序:
sort(a, a + 3)升序排列,使 \(a[0] \le a[1] \le a[2]\) - 确定正弦值:较小锐角的正弦 = \(\frac{a[0]}{a[2]}\)(最短边 / 最长边)
- 约分输出:
- \(g = \gcd(a[0], a[2])\)
- 输出
a[0]/g << "/" << a[2]/g
- 读入数据:
-
时间/空间复杂度:
- 时间复杂度:\(O(\log(\max(a)))\),主要由 GCD 计算决定,排序为 \(O(1)\)(固定3个数)
- 空间复杂度:\(O(1)\),仅需常数个变量
-
勾股数性质的核心思想:
- 排序定位边:排序后最小数为一条直角边,最大数为斜边(勾股数中斜边最大)
- 较小锐角判定:直角三角形中,较小锐角的对边较短,因此正弦值 = 最短直角边 / 斜边
- 最简分数:通过 GCD 约分,保证输出符合题目要求
- 欧几里得算法:递归实现 \(\gcd(a, b) = \gcd(b, a \bmod b)\),高效求最大公约数
- 适用于几何计算、分数约分、排序定位类入门问题
【算法标签】
入门 #数学
【代码详解】
#include <bits/stdc++.h> // 包含标准库头文件(万能头文件)
#include <algorithm> // 包含算法库(使用sort函数)
using namespace std; // 使用标准命名空间
/**
* 计算两个数的最大公约数(GCD)
* @param a 第一个整数
* @param b 第二个整数
* @return 最大公约数
*/
int gcd(int a, int b)
{
return 0 == b ? a : gcd(b, a % b); // 欧几里得算法递归实现
}
/**
* 主函数 - 程序入口
* @return 程序执行状态码(0表示成功)
*/
int main()
{
int a[3]; // 定义包含3个整数的数组
cin >> a[0] >> a[1] >> a[2]; // 输入三个整数
sort(a, a + 3); // 对数组进行升序排序
// 输出最简分数形式(最小数/最大数)
// 通过除以最大公约数进行约分
cout << a[0] / gcd(a[0], a[2]) << "/" << a[2] / gcd(a[0], a[2]);
return 0; // 程序正常结束
}
【运行结果】
3 5 4
3/5
浙公网安备 33010602011771号