[YNOI2019] 排队

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

按性别把身高分成两组,再分别按从矮到高排序后输出。

OJ: luogu

题目 ID: P5412

难度:入门

标签:排序模拟

日期: 2026-06-19 01:02

题意

给出一列同学的性别和身高。

要求把女生和男生分成两队,并且每一队内部都按照身高从矮到高输出。

从样例可以看出:

  • 0 表示女生
  • 1 表示男生

输出时先输出女生一行,再输出男生一行。

思路

最直接的做法就是:

  1. 扫描所有同学
  2. 按性别分别放进两个数组
  3. 再把两个数组各自排升序

下面这个朴素写法用冒泡排序,更方便读者直接理解“分组后分别排序”这件事:

cpp
// brute.cpp:直接分成男女两组,再用朴素排序把两组身高从小到大排好。
#include <bits/stdc++.h>
using namespace std;

int T, n;
int sex_[2005];

int parse_height(const string &s) {
    int value = 0;
    for (int i = 0; i < (int)s.size(); i++) {
        if (s[i] == '.') {
            continue;
        }
        value = value * 10 + (s[i] - '0');
    }
    return value;
}

void bubble_sort(vector<int> &a) {
    for (int i = 0; i < (int)a.size(); i++) {
        for (int j = 1; j < (int)a.size() - i; j++) {
            if (a[j - 1] > a[j]) {
                swap(a[j - 1], a[j]);
            }
        }
    }
}

void print_line(const vector<int> &a) {
    for (int i = 0; i < (int)a.size(); i++) {
        if (i) {
            cout << ' ';
        }
        cout << a[i] / 10 << '.' << a[i] % 10;
    }
    cout << '\n';
}

void solve_one_case() {
    vector<int> girls, boys;

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

    for (int i = 1; i <= n; i++) {
        string s;
        int h;
        cin >> s;
        h = parse_height(s);
        if (sex_[i] == 0) {
            girls.push_back(h);
        }
        else {
            boys.push_back(h);
        }
    }

    bubble_sort(girls);
    bubble_sort(boys);

    print_line(girls);
    print_line(boys);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> T;
    while (T--) {
        solve_one_case();
    }

    return 0;
}

正式做法只需要把朴素排序换成库函数 sort 即可。

代码

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

int T, n;
int sex_[2005];

int parse_height(const string &s) {
    int value = 0;
    for (int i = 0; i < (int)s.size(); i++) {
        if (s[i] == '.') {
            continue;
        }
        value = value * 10 + (s[i] - '0');
    }
    return value;
}

void print_line(const vector<int> &a) {
    for (int i = 0; i < (int)a.size(); i++) {
        if (i) {
            cout << ' ';
        }
        cout << a[i] / 10 << '.' << a[i] % 10;
    }
    cout << '\n';
}

void solve_one_case() {
    vector<int> girls, boys;

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

    for (int i = 1; i <= n; i++) {
        string s;
        int h;
        cin >> s;
        h = parse_height(s);
        if (sex_[i] == 0) {
            girls.push_back(h);
        }
        else {
            boys.push_back(h);
        }
    }

    sort(girls.begin(), girls.end());
    sort(boys.begin(), boys.end());

    print_line(girls);
    print_line(boys);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> T;
    while (T--) {
        solve_one_case();
    }

    return 0;
}

复杂度

设一组数据有 n 个同学。

时间复杂度是 O(nlogn)O(n log n),空间复杂度是 O(n)O(n)

总结

这题没有额外隐藏条件,本质就是“分类 + 排序”。

先把输出要求翻译成数据操作,代码就很直接。