Python-CCF:20190904 推荐系统

题目

在这里插入图片描述
在这里插入图片描述

用时

贼长,一度想放弃(最终还是放弃了)
在这里插入图片描述
2020.02.24
突然想起来运行错误很可能和split有关
改了以后又提交了一次终于不是运行错误了!
但是运行超时拿了十分,sigh

测试用例参考

C++满分代码

还是有问题
在这里插入图片描述题目要求是同类商品的编号从小到大输出
但是那个C++满分代码中
第13行,3 10 2 2 的输出编号是3 2
就比较迷
人家也确实是满分

在这里插入图片描述
我的10分超时版本改成从小到大的反而一分都没了
坑爹
在这里插入图片描述

思路

  1. 每件货物都是一个对象,有类别,编号,得分的信息
  2. 写三个方法分别对应增删查
  3. 其中比较复杂的是查方法,首先要理解输入格式,比如3 1 1 1
    3代表查操作的操作码
    第一个1是最后只要一件符合条件的货物
    第二个1是指从第一类商品中选择不超过一件货物
    第三个1是指从第二类商品中选择不超过一件货物
  4. 我用了Python多关键字排序的方法实现了题目说的同分货物替换
all_chaos_cargo_list.sort(key=lambda co: (-co.score, co.which_type, co.commodity))

其实也并不能说是替换,只是将每类选出的前几件高分的货物按分倒序排序,按类正序排序,按编号正序排序,最终只选择不超总限额数的排名靠前的几件货物,但是运行超时了
(倒序即从大到小,正序反之)

运行超时10分代码

class Cargo:
    # 货物类

    which_type = 0
    # 商品类型
    commodity = 0
    # 货物在本类商品中的编号
    score = 0
    # 本货物的分数

    def set_type_commodity_score(self, which_type, commodity, score):
        # 设置本货物的商品类型、编号和分数
        self.which_type = which_type
        self.commodity = commodity
        self.score = score


def insert(all_type_cargo, operate_list):
    # 向which_type类商品中插入编号为commodity,分数为score的货物
    which_type, commodity, score = map(int, operate_list.split())
    new_cargo = Cargo()
    new_cargo.set_type_commodity_score(which_type, commodity, score)
    all_type_cargo[which_type].append(new_cargo)


def delete(all_type_cargo, operate_list):
    # 从which_type类商品中删除编号为commodity的货物
    which_type, commodity = map(int, operate_list.split())
    for cargo_obj in all_type_cargo[which_type]:
        if cargo_obj.commodity == commodity:
            all_type_cargo[which_type].remove(cargo_obj)


def select(all_type_cargo, limit_count_k, select_rule_list):
    # 总货物单,选择货物的总数,选择的规范

    select_rule_list = list(map(int, select_rule_list.split()))

    all_chaos_cargo_list = []
    # 与type无关的乱序高分货物清单
    """
        格式为[高分货物1,高分货物2..]
    """

    for srl_n in range(len(select_rule_list)):
        all_type_cargo[srl_n].sort(key=lambda co: co.score, reverse=True)
        # 对本类商品中的每个货物对象按得分从大到小排序
        for i in all_type_cargo[srl_n][0:select_rule_list[srl_n]]:
            all_chaos_cargo_list.append(i)
            # 不考虑总限额,按选择规范,将每类前n个高分货物全部添加至乱序高分货物清单

    all_chaos_cargo_list.sort(key=lambda co: (-co.score, co.which_type, co.commodity))
    # 按分倒序排序,按类正序排序,按编号正序排序

    chosen_type_cargo_list = all_chaos_cargo_list[0:limit_count_k]
    # 最终按总限额选取高分货物

    # chosen_type_cargo_list.sort(key=lambda co: (co.which_type, co.commodity))
    # 同类商品再按编号正序排序而非高分

    return chosen_type_cargo_list


if __name__ == '__main__':
    type_num, type_cargo_num = map(int, input().split())
    # 几类商品,每类商品有多少件货物
    all_type_cargo = [[Cargo() for tcn in range(type_cargo_num)] for tn in range(type_num)]
    """格式为
    [
        [家电1,家电2..],    type=0
        [汽车1,汽车2..],    type=1
        [电动车1,电动车2..],    type=m-1
    ]
        注意type从0开始,commodity从1开始
    """

    for tcn in range(type_cargo_num):
        commodity, score = map(int, input().split())
        # 每类商品中编号为commodity的商品的得分都为score
        for tn in range(type_num):
            all_type_cargo[tn][tcn].set_type_commodity_score(tn, commodity, score)
            # 注意区分下标tcn和编号

    operate_num = int(input())
    for on in range(operate_num):
        operate_type, operate_list = input().split(None, 1)
        if operate_type == '1':
            # 如果是增操作
            insert(all_type_cargo, operate_list)

        elif operate_type == '2':
            # 如果是删操作
            delete(all_type_cargo, operate_list)
        elif operate_type == '3':
            limit_count_k, select_rule_list = operate_list.split(None, 1)
            chosen_type_cargo_list = select(all_type_cargo, int(limit_count_k), select_rule_list)
            for tn in range(type_num):
                chosen = False
                # 本类中是否有被选中的商品

                for co in chosen_type_cargo_list:
                    if co.which_type == tn:
                        # 如果有
                        chosen = True
                        print(co.commodity, end=" ")
                if not chosen:
                    print(-1, end=" ")
                print()

测试用例一
1 3
1 3
2 2
3 1
8
3 100 1
1 0 4 4
1 0 5 5
3 10 2
2 0 2
3 1 1
2 0 1
3 1 1

输出
1
5 4
5
5

测试用例二
1 3
1 1
2 2
3 3
4
3 0 1
3 0 2
3 0 3
3 0 4

输出
-1
-1
-1
-1
测试用例三
2 3
1 1
2 2
3 3
8
3 100 1 1
1 0 4 3
1 0 5 1
3 10 2 2
3 10 1 1
2 0 1
3 2 1 1
3 1 1 1


输出
3
3
3 4
3 2
3
3
3
3
3
-1
测试用例四
3 4
1 4
2 3
3 2
4 1
8
3 100 1 1 2
1 0 5 3
1 0 6 1
3 10 2 2 10
3 10 1 1 10
2 0 1
3 2 1 1 5
3 1 1 1 5


输出
1
1
1 2
1 2
1 2
1 2 3 4
1
1
1 2 3 4
-1
1
1
-1
1
-1

反思

最起码应该在手动根据输入计算一遍输出后再开始写代码,你以为的理解了题意只是你以为
不要为了节省时间匆匆上手敲代码,最终的结果可能是事倍功半
惨痛教训
但是上面的测试用例和满分代码输出都一样,可能是还有没有覆盖到的地方
死心了已经,太耗时间
(另外题目描述和打分并不一致,如前所说,所以还是有些怀疑)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值