【C++】B2065 鸡尾酒疗法

发布于:2025-02-11 ⋅ 阅读:(56) ⋅ 点赞:(0)

在这里插入图片描述

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳]
本文专栏: C++

在这里插入图片描述


在这里插入图片描述


💯前言

  • 在本次学习中,我们共同分析了一道关于功效率绘占比例比较的题目,该题目根据输入数据,判断两种治疗方法的效果是否有所改善,比如是否“better”,“worse”或“same”。我们分别分析了老师的代码和我们之前的解法,并将对两者进行了对比,提出了有效的优化方式,还进行了一些知识扩展,以加强学习效果。
    下面将通过清晰的结构将上述内容统一积累为一篇详细的分析文章,便于读者阅读和学习。
    C++ 参考手册
    在这里插入图片描述

💯题目描述

B2065 鸡尾酒疗法
在这里插入图片描述

题目要求如下:

  1. 输入包含治疗方法的功效率 s1s2;
  2. 比较这两次功效率的改善幅度:
    • 如果改善幅度超过 5%(即大于 0.05),则输出 better
    • 如果退步幅度超过 5%(即小于 -0.05),则输出 worse
    • 否则,输出 same

输入格式

  • 第一行为测试组的数量(正整数 n)。
  • 后续每行包含两个正整数 s1s2,分别表示治疗方法的前后功效率。

输出格式

  • 对每一组输入,根据判断解析输出 betterworse,或 same

💯老师的做法分析

下面是老师的代码:

#include <iostream>
using namespace std;

int n;
float x, y;
int a, b;

int main() {
    cin >> n;
    cin >> a >> b;
    x = b * 1.0 / a;
    for (int i = 0; i < n - 1; i++) {
        cin >> a >> b;
        y = b * 1.0 / a;
        if (y - x > 0.05)
            cout << "better" << endl;
        else if (x - y > 0.05)
            cout << "worse" << endl;
        else
            cout << "same" << endl;
    }
    return 0;
}

在这里插入图片描述

分析

代码流程分析

  1. 在代码的上半部,创建了一些基础变量:

    • int n:表示测试组数。
    • float x, y:分别用于记录基准比例和当前比例。
    • int a, b:用于输入每一组数据。
  2. 初始化:

    • 第一个 cin 进行数组的输入:n
    • 通过第一次输入取得 ab,并计算基准比例:x = b * 1.0 / a;,这是后续判断的基准。
  3. 循环处理:

    • 通过一个 for 循环,进行后续数据测试的比例计算和判断:
      for (int i = 0; i < n - 1; i++) {
          cin >> a >> b;
          y = b * 1.0 / a;
      }
      
    • 比较当前比例 y 与基准比例 x 的差值:
      • 如果 y - x > 0.05,输出 better
      • 如果 x - y > 0.05,输出 worse
      • 否则,输出 same
  4. 返回值:

    • 最后通过 return 0;,程序正常退出。

老师代码的优点

  • 清晰的初始化逻辑:将第一次输入单独处理,避免在循环中进行特殊判断,代码逻辑更清晰。
  • 变量命名规范:变量 xy 清楚地表示了基准比例和当前比例,便于理解。
  • 结构简单直观:代码结构紧凑,逻辑分明,适合快速实现和阅读。

老师代码的潜在改进点

  1. 浮点数精度问题

    • 浮点数比较时,直接使用 y - x > 0.05x - y > 0.05 可能存在精度误差。
    • 可以使用 fabs(y - x),确保绝对值比较时的鲁棒性。
  2. 循环次数的控制

    • 当前循环次数为 n - 1,因为第一组数据在循环外处理。但如果数据规模更大,这种处理方式可能会让读者误解。
  3. 代码扩展性

    • 如果未来需要对比例判断的逻辑进行扩展,例如添加新的规则,当前代码的紧凑结构可能不易扩展。

💯我们的解法分析

我们的代码实现如下:

#include <iostream>
using namespace std;

int main()
{
	int n = 0;
	double x = 0, y = 0;
	cin >> n;
	for(int i = 1; i <= n; i++)
	{
		double s1 = 0, s2 = 0;
		cin >> s1 >> s2;
		if(i == 1)
			x = s2 * 1.0 / s1;
		else
		{
			y = s2 * 1.0 / s1;
			if((y - x) > 0.05)
				cout << "better" << endl;
			else if((x - y) > 0.05)
				cout << "worse" << endl;
			else
				cout << "same" << endl;
		}
	} 
	
	return 0;
}

在这里插入图片描述

分析

代码流程分析

  1. 变量初始化

    • 使用 double x = 0, y = 0; 初始化比例变量。
    • 变量作用域被限制在循环内,更加局部化,避免了不必要的全局变量。
  2. 输入处理

    • 第一次循环时,计算基准比例 x
    • 从第二次循环开始,计算当前比例 y 并进行比较。
  3. 比较逻辑

    • 通过 if-else 判断比例差值:
      • 如果 y - x > 0.05,输出 better
      • 如果 x - y > 0.05,输出 worse
      • 否则,输出 same

我们代码的优点

  1. 循环范围一致

    • 循环从 i = 1 开始,到 i <= n,统一了处理逻辑。
    • 所有输入均在循环中完成,逻辑更集中。
  2. 使用浮点数绝对值比较

    • 如果需要,可以扩展为:
      if (fabs(y - x) > 0.05)
      
      避免浮点数精度问题。
  3. 局部变量的使用

    • 将比例计算变量限制在循环内部,代码更简洁,减少了全局变量的使用。

我们代码的潜在改进点

  • 代码逻辑复杂度稍高
    • 在循环中判断 i == 1 是特例处理,增加了循环的复杂性。
    • 如果需要扩展,可能需要进一步调整代码结构。

💯两种解法对比与优化建议

对比

对比项 老师代码 我们的代码
初始化逻辑 第一次输入在循环外,逻辑更清晰 初始化在循环内,逻辑稍复杂
变量使用 全局变量 x, y, a, b 明确但冗余 局部变量更简洁,作用域更小
循环范围 for (int i = 0; i < n - 1; i++) for (int i = 1; i <= n; i++)
浮点数比较 直接比较浮点数,有潜在精度问题 可扩展为绝对值比较,精度更高

优化建议

  1. 浮点数精度处理

    • 使用 fabs(y - x) 确保比较的精度。
  2. 循环逻辑优化

    • 可以统一第一次数据的处理方式,将初始化逻辑集中到循环内。
  3. 扩展性增强

    • 可以通过函数封装比例计算和判断逻辑,提高代码的可读性和复用性。

💯完整优化代码

结合两种方法的优点,经过优化后得到如下代码:

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

void compareEfficiency(double baseRatio, double currentRatio) {
    if (currentRatio - baseRatio > 0.05)
        cout << "better" << endl;
    else if (baseRatio - currentRatio > 0.05)
        cout << "worse" << endl;
    else
        cout << "same" << endl;
}

int main() {
    int n;
    cin >> n;

    double baseRatio = 0.0;
    for (int i = 0; i < n; i++) {
        int s1, s2;
        cin >> s1 >> s2;

        double currentRatio = s2 * 1.0 / s1;
        if (i == 0)
            baseRatio = currentRatio;
        else
            compareEfficiency(baseRatio, currentRatio);
    }

    return 0;
}

💯总结

在这篇文章中,我们分析了老师的代码和我们的解法,通过对比发现了各自的优缺点,并结合两者的优势给出了优化后的最终代码。浮点数精度处理、代码结构优化、函数封装是改进的重点方向。这种方法不仅提高了代码的可读性,也为后续扩展打下了良好的基础。希望这篇文章能够帮助读者更好地理解和掌握 C++ 的编程技巧!


在这里插入图片描述



网站公告

今日签到

点亮在社区的每一天
去签到