病人排队

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

用排序键同时表达老人优先、年龄降序和登记顺序保持规则。

OJ: noi_openjudge

题目 ID: ch0110-08

难度:入门

标签:排序模拟python

日期: 2026-07-30 23:01

题意

老人(年龄不小于 60 岁)优先看病,老人中年龄大的在前、同龄保持登记顺序;非老人全部保持登记顺序。

思路

保存 (编号, 年龄, 登记顺序)。排序键的第一项 年龄 < 60 对老人是 False、对非老人是 True,所以老人排在前;第二项只有对老人使用 -年龄,让老人年龄降序;最后的登记顺序保证同龄老人和所有非老人都按原顺序排列。

Python 的排序本身稳定,但把登记顺序写进键中能将全部规则明确地表达出来。

代码

Python代码

python
patient_count = int(input())
patients = []

for order in range(patient_count):
    patient_id, age = input().split()
    age = int(age)
    patients.append((patient_id, age, order))

# 年龄不足 60 的人排在后面;同龄老人和所有非老人按登记次序保持稳定。
patients.sort(
    key=lambda patient: (
        patient[1] < 60,
        -patient[1] if patient[1] >= 60 else 0,
        patient[2],
    )
)
for patient_id, _, _ in patients:
    print(patient_id)

C++代码

cpp
#include <cstdio>

char id[200][100];

int n;
struct _p {
    int id,age,ord;
};
_p p[200];
void init(){
    scanf("%d",&n);
    int i;
    for (i=1;i<=n;i++){
        scanf("%s",id[i]);
        scanf("%d",&p[i].age);
        p[i].id = i;
        p[i].ord = i;
    }
}

// >=
bool greater(_p &a,_p &b){

    if(a.ord == b.ord) return 1;
    if( a.age >=60 && b.age < 60)
        return 1;

    if( a.age >=60 &&  b.age >=60 ){
        if( a.age > b.age)
            return 1;
        else if ( a.age == b.age)
            return a.ord < b.ord;
    }

    if( a.age < 60 && b.age < 60){
        return a.ord < b.ord;
    }

    return 0;
}

void xchg( _p &a, _p &b){
    _p t = a;
    a = b;
    b = t;
}
void quick_sort(int l,int r){
    if( l >= r ) return;

    _p key = p[l];
    int i= l,j = r;

    while(i!= j){
        while( i < j && greater(p[j],key))
            j--;
        while( i < j && greater(key,p[i]))
            i++;
        if( i < j)
            xchg(p[i], p[j]);
    }
    p[l] = p[i];
    p[i] = key;
    quick_sort(l, i-1);
    quick_sort(i+1, r);
}

int main(){
    init();
    quick_sort(1, n);
    int i;
    for(i = n;i>=1;i--)
        printf("%s\n",id[ p[i].id ]);
    return 0;
}

复杂度

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

总结

遇到“优先级 + 保持原顺序”的规则,可将优先级和原始下标依次放入排序键。