【PAT_Python解】1015 德才论

原题链接:PTA | 程序设计类实验辅助教学平台

【原文链接】:1015 德才论 (Python 无超时 详解)_pta 1015 python-CSDN博客

Tips:以下Python代码纯转发AC答案,本人未满,以后再做AC!

import sys
 
def p_list(info):
    # 根据题目要求从大到小输出实际存在的分数
    for i in range(201, 0, -1):
        for j in range(100, 0, -1):
    # 如果当前有值,则通过sorted排序返回一个列表,用for遍历这个排序好的列表依次输出即可
    # 这里存储的是准考证号,要求从小到大
            if info[i][j]:
                for k in sorted(info[i][j]):
                    sys.stdout.write("%s %s %s\n" % (k, j, i - j))
def main():
    # 通过列表推导式创建三维列表,为info[][][], 从前往后分别表示总分,德分,准考证号
    info1 = [[[] for i in range(101)] for j in range(202)]
    info2 = [[[] for i in range(101)] for j in range(202)]
    info3 = [[[] for i in range(101)] for j in range(202)]
    info4 = [[[] for i in range(101)] for j in range(202)]
 
    cnt = 0
    
    n, l, h = map(int, input().split())
    a = [list(map(int, sys.stdin.readline().split())) for i in range(n)]
    for x in a:
        # 不满足题目要求的学生不予存入
        if x[1] < l or x[2] < l:
            continue
        
        # 由于准考证号值过大,无法通过索引形式,只能append添加至末尾
        if x[1] >= h and x[2] >= h:
            info1[x[1] + x[2]][x[1]].append(x[0])
        elif x[1] >= h:
            info2[x[1] + x[2]][x[1]].append(x[0])
        elif x[1] >= x[2]:
            info3[x[1] + x[2]][x[1]].append(x[0])
        else:
            info4[x[1] + x[2]][x[1]].append(x[0])
        cnt += 1
 
    sys.stdout.write("%s\n" % cnt)
    p_list(info1)
    p_list(info2)
    p_list(info3)
    p_list(info4)
main()

通过列表推导式创建三维列表,为info[][][], 从前往后分别表示总分,德分,准考证号

最大为info[201[100][],总分<=200,单科<=100

通过形如进行数据添加:(不是每个坐标都有数据,所以输出时需要判断shif,if info[i][j]:)

            info1[x[1] + x[2]][x[1]].append(x[0])

info[总分]        [德分]        [准考证号]        最终输出时,才分=总分-德分

循环遍历三维列表,需要判断当前[][]坐标是否有值(准考证号),然后进行准考证号排序【sorted(info[i][j])】,如输入样例,会得出(总分降序,同分则德分降序,同分则准考证号升序)

[10000013]
[10000012]
[10000011, 10000003]                通过遍历in排序sorted得出
[10000004]
[10000007]
[10000006]
[10000005]
[10000002]
[10000014]
[10000008]
[10000001]

### C++ 中 `std::map` 按照 Value 进行排序 由于标准库中的 `std::map` 是基于键(key)进行自动排序的数据结构,无法直接按照值(value)排序。为了实现按值排序的需求,通常有两种方法: #### 方法一:创建自定义比较器并使用 `std::set` 通过将 `std::pair<const T2, K>` 存储于 `std::set` 或者 `std::multiset` 来间接达到目的。这里假设有一个 `std::map<K,T2>` 类型的对象。 ```cpp #include <iostream> #include <map> #include <set> // 定义一个辅助结构体用于反转 key 和 value 的顺序以便根据 value 排序 struct Pair { int val; const char* name; bool operator<(const Pair& rhs) const { return this->val < rhs.val; // 根据 value 值升序排列 } }; int main() { std::map<int, const char*> originalMap = {{1, "apple"}, {3, "banana"}, {2, "orange"}}; // 将 map 转换成 set 并依据 value 排序 std::set<Pair> sortedByValueSet; for (auto&& elem : originalMap) { sortedByValueSet.insert({elem.second, elem.first}); } // 输出结果 for (auto it = sortedByValueSet.rbegin(); it != sortedByValueSet.rend(); ++it){ std::cout << "Key: " << it->name << ", Value: " << it->val << '\n'; } return 0; } ``` 这种方法利用了 `std::set` 自动维护内部元素有序性的特点,并且可以通过重载 `<` 操作符来自定义排序逻辑[^1]。 #### 方法二:转换成向量再排序 另一种常见的方式是先将所有的键值对复制到一个支持随机访问迭代器的容器里(比如 `std::vector<std::pair<KeyType, ValueType>>`),之后调用通用算法如 `std::sort()` 对其执行排序操作。 ```cpp #include <iostream> #include <map> #include <vector> #include <algorithm> int main(){ std::map<int,std::string> my_map{{1,"z"},{2,"b"},{3,"a"}}; // 创建 vector<pair<...>> std::vector<std::pair<int, std::string>> vec(my_map.begin(),my_map.end()); // 使用 lambda 表达式指定排序条件 sort(vec.begin(),vec.end(), [](const auto& lhs,const auto& rhs){return lhs.second<rhs.second;} ); // 打印排序后的结果 for(auto& p : vec){ std::cout<<p.first<<" => "<<p.second<<"\n"; } return 0; } ``` 此代码片段展示了如何把原始映射表的内容转移到一个新的动态数组中去处理,从而允许我们灵活地调整排序规则[^2]。 这两种方式各有优劣,在实际应用时可以根据具体需求选择合适的做法。如果只需要一次性获取一次排序的结果,那么第二种方案可能更加简单直观;而如果是频繁查询最大小项等情况,则建议采用第一种方案构建静态索引以提高效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

新时代先锋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值