小鱼比可爱

GitHub跳转原题关系图返回列表

对每条小鱼枚举它左边的所有小鱼,统计可爱程度严格更小的数量。

OJ: luogu

题目 ID: P1428

难度:入门

标签:模拟枚举列表python

日期: 2026-07-15 18:44

题意

给出从左到右 n 条小鱼的可爱程度。每条小鱼只能看到自己左边的小鱼,要求输出每条小鱼左边有多少条小鱼的可爱程度严格小于它。

注意相等不算“不如自己可爱”。

思路

数据范围只有 n <= 100,可以直接按定义做双重循环。

对第 i 条小鱼,枚举所有 j < i 的小鱼。如果:

text
a[j] < a[i]

就把计数加一。把每个位置的计数放入 answer,最后一行输出。

从教学视角看,也可以先生成候选对,再过滤计数:

python
# 先生成再 filter(教学视角)
answer = []
for i in range(n):
    pairs = [(i, j) for j in range(i)]
    answer.append(sum(1 for _, j in pairs if a[j] < a[i]))

含义是:

  1. 对每个 i,先生成所有左边下标对 (i, j),其中 j < i
  2. filtera[j] < a[i] 的对;
  3. sum / len 得到答案。

实战中通常直接双重循环边枚举边计数,不必真的建 pairs 列表;n <= 100 两种写法都可以。

这题是数组枚举入门,正解就是直接实现定义,不创建 brute.py

Python 知识

  • /home/rainboy/mycode/hugo-blog/content/program_language/python/input_output_and_strings.md:使用 list(map(int, input().split())) 读取一行整数数组。
  • /home/rainboy/mycode/hugo-blog/content/program_language/python/brute_force_validation.mdrange(i) 可以枚举当前位置左边的下标 0..i-1
  • 列表推导 [(i, j) for j in range(i)] 可先生成候选对,再过滤。
  • sum(1 for ... if ...) 适合对满足条件的元素计数。
  • print(*answer) 会用空格输出列表中的所有元素。

代码

python
from itertools import combinations

n = int(input())
a = list(map(int, input().split()))
pairs = list(filter(lambda p: a[p[0]] < a[p[1]], combinations(range(n), 2)))
print(*(len([p for p in pairs if p[1] == i]) for i in range(n)))
cpp
/**
 * Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
 * rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
 * rainboy的学习导航网站: https://idx.roj.ac.cn
 * create_at: 2026-07-27 00:00
 * update_at: 2026-07-27 00:00
 */

#include <bits/stdc++.h>
using namespace std;

int a[105];   // 每条小鱼的可爱程度
int ans[105]; // ans[i] = 第 i 条小鱼左边比它可爱的小鱼数量
int n;

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i];

    // 对每条小鱼,枚举它左边的所有小鱼
    for (int i = 1; i <= n; i++) {
        int cnt = 0;
        for (int j = 1; j < i; j++) {
            if (a[j] < a[i]) cnt++; // 严格小于才算"不如自己可爱"
        }
        ans[i] = cnt;
    }

    for (int i = 1; i <= n; i++) cout << ans[i] << " ";
    return 0;
}

Pythonic 写法

combinations + 计数:

python
from itertools import combinations
n = int(input())
a = list(map(int, input().split()))
pairs = [(j, i) for j, i in combinations(range(n), 2) if a[j] < a[i]]
print(*(sum(i == t for _, i in pairs) for t in range(n)))

复杂度

双重循环枚举左侧元素,时间复杂度是 O(n2)O(n^2);答案数组需要 O(n)O(n) 空间。

总结

这题的关键是保持“只看左边”和“严格小于”两个条件。范围很小,直接枚举比引入复杂数据结构更适合入门学习。