题解:洛谷 P1428 小鱼比可爱

【题目来源】

洛谷:P1428 小鱼比可爱 - 洛谷

【题目描述】

人比人,气死人;鱼比鱼,难死鱼。小鱼最近参加了一个“比可爱”比赛,比的是每只鱼的可爱程度。参赛的鱼被从左到右排成一排,头都朝向左边,然后每只鱼会得到一个整数数值,表示这只鱼的可爱程度,很显然整数越大,表示这只鱼越可爱,而且任意两只鱼的可爱程度可能一样。由于所有的鱼头都朝向左边,所以每只鱼只能看见在它左边的鱼的可爱程度,它们心里都在计算,在自己的眼力范围内有多少只鱼不如自己可爱呢。请你帮这些可爱但是鱼脑不够用的小鱼们计算一下。

【输入】

第一行输入一个正整数 \(n\),表示鱼的数目。

第二行内输入 \(n\) 个正整数,用空格间隔,依次表示从左到右每只小鱼的可爱程度 \(a_i\)

【输出】

一行,输出 \(n\) 个整数,用空格间隔,依次表示每只小鱼眼中有多少只鱼不如自己可爱。

【输入样例】

6 4 3 0 5 1 2

【输出样例】

0 0 0 3 1 2

【核心思想】

  1. 问题分析:有 \(n\) 条鱼从左到右排列,每条鱼有一个可爱程度 \(a_i\)。每条鱼只能看到它左边的鱼,需要统计左边有多少条鱼的可爱程度严格小于自己的可爱程度。本质是对序列中的每个元素,统计其左侧小于该元素的数量

  2. 算法选择

    • 双重循环(暴力统计):对于第 \(i\) 条鱼,遍历 \(1\)\(i-1\) 的所有鱼,统计 \(a_j < a_i\) 的个数。这种方法简单直接,时间复杂度 \(O(n^2)\),对于 \(n\) 最大为 \(100\)(题目未明确,但通常数据规模较小)完全可行。
    • 更优方法:如果 \(n\) 较大,可以使用树状数组或归并排序进行优化,但本题作为入门题,双重循环即可。
  3. 关键步骤

    • 读入:读取 \(n\) 和数组 \(a[1..n]\)
    • 外层循环:对于 \(i\)\(1\)\(n\),初始化计数器 sum = 0
    • 内层循环:对于 \(j\)\(1\)\(i-1\),若 \(a[j] < a[i]\),则 sum++
    • 输出:输出 sum(用空格分隔)。
    • 注意:由于鱼头朝左,每条鱼只能看见左边的鱼,因此统计的是左侧小于当前值的数量,不包括右侧或自身。
  4. 时间/空间复杂度

    • 时间复杂度:\(O(n^2)\)\(n\) 通常 \(\le 100\),可接受。
    • 空间复杂度:\(O(n)\),存储数组。
  5. 模拟与逆序对简化

    • 问题本质:这是一个简化版的逆序对统计,但只要求左侧小于当前元素的数量,不要求全局逆序对(即不统计右侧小于当前元素的数量),因此只需对每个元素分别向左扫描。
    • 严格小于:因为“不如自己可爱”指可爱程度严格小于自己,所以条件为 a[j] < a[i],不包括相等的情况。
    • 适用场景:这种“每个元素统计左侧满足某条件的元素个数”是入门级模拟的经典题型,也可用于理解前缀统计思想。

【算法标签】

入门 #模拟

【代码详解】

#include <bits/stdc++.h>  // 包含标准库头文件(万能头文件)
using namespace std;      // 使用标准命名空间

/**
 * 主函数 - 程序入口
 * @return 程序执行状态码(0表示成功)
 */
int main()
{
    int n;               // 定义变量:数组元素个数
    int a[105];         // 定义数组:存储输入的数字序列
    int sum;            // 定义变量:计数器,统计比当前元素小的元素个数

    cin >> n;           // 输入数组元素个数

    // 输入数组元素
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
    }

    // 遍历数组,计算每个元素前面比它小的元素个数
    for (int i = 1; i <= n; i++)
    {
        sum = 0;        // 重置计数器

        // 遍历当前元素之前的所有元素
        for (int j = 1; j <= i - 1; j++)
        {
            // 如果前面的元素比当前元素小
            if (a[j] < a[i])
            {
                sum++;  // 计数器加1
            }
        }

        // 输出当前元素前面比它小的元素个数
        cout << sum << " ";
    }

    return 0;           // 程序正常结束
}

【运行结果】

6
4 3 0 5 1 2
0 0 0 3 1 2
posted @ 2026-08-30 09:17  团爸讲算法  阅读(13)  评论(0)    收藏  举报