Auction Bidding 2017ACM-ICPC亚洲区(南宁赛区)网络赛C题

**题意:**ABC 公司举行了一场拍卖,有 N 个拍卖物品,编号从 1 到 N,并且有 M 个竞标人,编号为 1 到 M。竞标有一些规则:
1.每个物品有一个保留价格,为正数
2.每个竞标人最多给每个物品出一个价格,为正数
3.竞标人出的价格只有高于物品的保留价格时才是一个有效的价格。无效的价格不被考虑。
4.出价最高的有效价格赢得物品。如果存在两个相同的最高有效价格,那么竞标人编号小的赢得物品。
5.一个竞标人赢得了物品,则成交价为第二大的有效竞标价乘以10%的结果和最大的竞标价中较小的一个。如果价格不是整数,则向下取整。
6.第二大的有效竞标价如果不存在,则视作物品的保留价格。
题目要求每个竞标人最终花了多少钱。

思路:题目有点长,但是还是比较简单的,自己竟然做了那么久。一开始想的是读取完前 N+2 行数据后,算出每个物品拍给了谁或没拍出去了。然后就能算出每个投标人一共花了多少钱了。写了好久感觉很乱。后来看队友写的思路大概是每读取完一条数据就算出这个物品卖给谁,这样子实现起来更加的方便。

做题目前思路一定要清晰,而且一个好的思路实现起来也会简单很多,不易出错。
代码:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <time.h>
#include <stack>
#include <queue>
#include <vector>
#include <fstream>
using namespace std;
#define LL long long int

int N, M;
LL R[1010];  //物品的保留价格
int B[1010];  //物品卖给谁了
LL P[1010]; //物品的最终定价

struct Bid{
    int b;
    LL p;
    Bid(){}
    Bid(int a, LL c):b(a),p(c){}
    bool operator < (const Bid& bid){
        if(p == bid.p) return b<bid.b;
        else return p>bid.p;
    }
};

int main()
{
    //freopen("in.txt", "r", stdin);
    scanf("%d%d", &N, &M);
    for(int i=1; i<=N; i++){   //读取一行数据处理一行
        scanf("%d", &R[i]);
        int b;
        LL p;
        vector<Bid> vec;
        while(scanf("%d", &b)==1 && b!=-1){
            scanf("%lld", &p);
            if(p < R[i]) continue;
            vec.push_back(Bid(b, p));
        }
        sort(vec.begin(), vec.end());

        if(vec.size() == 0){  //该物品没有人买或没有有效的价格
            B[i] = 0;
            P[i] = 0;
        }
        else if(vec.size() == 1){   //该物品只有一个人买或只有一个有效的价格
            B[i] = vec[0].b; 
            P[i] = min(vec[0].p, (LL)(R[i]*1.1));
        }
        else{   //该物品有多个人买或有多个有效的价格
            B[i] = vec[0].b;
            P[i] = min(vec[0].p, (LL)(vec[1].p*1.1));
        }
    }

    int k, q;
    scanf("%d", &k);
    while(k--){
        scanf("%d", &q);
        LL ans = 0;
        for(int i=1; i<=N; i++){
            if(B[i] == q){
                ans += P[i];
            }
        }
        printf("%lld\n", ans);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值