题解:洛谷 P1888 三角函数

【题目来源】

洛谷:P1888 三角函数 - 洛谷

【题目描述】

输入一组勾股数 \(a,b,c(a\neq b\neq c)\),用分数格式输出其较小锐角的正弦值。(要求约分。)

【输入】

一行,包含三个正整数,即勾股数 \(a,b,c\)(无大小顺序)。

【输出】

一行,包含一个分数,即较小锐角的正弦值

【输入样例】

3 5 4

【输出样例】

3/5

【核心思想】

  1. 问题分析:给定一组勾股数 \(a, b, c\)(无大小顺序),要求输出较小锐角的正弦值(约分后的最简分数)。在直角三角形中,较小锐角对应较短的直角边,其正弦值 = 对边(最短直角边)/ 斜边(最长边,即 \(c\))。

  2. 算法选择

    • 排序确定边:将三数排序后,\(a[0]\) 为最短直角边(较小锐角的对边),\(a[2]\) 为斜边
    • 欧几里得算法求 GCD:计算分子分母的最大公约数进行约分
  3. 关键步骤

    • 读入数据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
  4. 时间/空间复杂度

    • 时间复杂度:\(O(\log(\max(a)))\),主要由 GCD 计算决定,排序为 \(O(1)\)(固定3个数)
    • 空间复杂度:\(O(1)\),仅需常数个变量
  5. 勾股数性质的核心思想

    • 排序定位边:排序后最小数为一条直角边,最大数为斜边(勾股数中斜边最大)
    • 较小锐角判定:直角三角形中,较小锐角的对边较短,因此正弦值 = 最短直角边 / 斜边
    • 最简分数:通过 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
posted @ 2026-08-05 15:45  团爸讲算法  阅读(22)  评论(0)    收藏  举报