CodeForces - 799B T-shirt buying

T-shirt buying
题 意:一家商店有n件T-shirt,每件T-shirt 都有一个价格pi,和正面的颜色ai和后面的颜色bi,有m个顾客来商店按编号从1-m依次购买自己喜欢的衣服,每个顾客都买一件衣服,每个顾客都有一个喜欢的颜色,只要一件衣服前面或者后面出现了那种颜色顾客就会酒席。每次顾客都买最便宜的那件自己的喜欢的。问每个顾客付的价钱是多少?如果没有顾客喜欢的衣服则输出-1。

数据范围:
1<=n,m<=20 0000
1<=pi<=1e6
1<=ai,bi<=3

输入样例:

5
300 200 400 500 911
1 2 1 2 3
2 1 3 2 1
6
2 3 1 2 1 1

输出样例:

200 400 300 500 911 -1 

思 路:这题的n,m有点大,o(nm)肯定是过不去,但是ai和bi却很小,可以用3个优先队列来维护一下三种颜色的衣服。每次从里面取出一件最小的。这样所有队列里面最多有2n个元素。那也就是mlg(2n)的复杂度。这样应该是可以过的。

收 获:要养成写代码的好习惯,可以避免很多错误。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5+5;
const int INF = 0x3f3f3f3f;
struct node{
    int p,x,y;
    int id;
    bool operator<(const node _a)const{
        return p>_a.p;
    }
}a[maxn];
bool vis[maxn];
int b[maxn];
priority_queue<node> que[4];
int n,m;
int main(){
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        a[i].id = i;
        scanf("%d",&a[i].p);
    }
    for(int i=0;i<n;i++){
        scanf("%d",&a[i].x);
        if(a[i].x == 1){
            que[1].push(a[i]);
        }else if(a[i].x == 2){
            que[2].push(a[i]);
        }else if(a[i].x == 3){
            que[3].push(a[i]);
        }
    }
    for(int i=0;i<n;i++){
        scanf("%d",&a[i].y);
        if(a[i].y == 1){
            que[1].push(a[i]);
        }else if(a[i].y == 2){
            que[2].push(a[i]);
        }else if(a[i].y == 3){
            que[3].push(a[i]);
        }
    }
    scanf("%d",&m);
    for(int i=0;i<m;i++)scanf("%d",&b[i]);
    for(int i=0;i<m;i++){
        if(b[i] == 1){
            if(que[1].empty()){
                printf("%d%c",-1,i==m-1?'\n':' ');
                continue;
            }else{
                bool flag = false;
                while(!que[1].empty()){
                    node no = que[1].top();que[1].pop();
                    if(vis[no.id]) continue;
                    else{
                        flag = true;
                        vis[no.id] = true;
                        printf("%d%c",no.p,i==m-1?'\n':' ');
                        break;
                    }
                }
                if(!flag){
                    printf("%d%c",-1,i==m-1?'\n':' ');
                }
            }
        }else if(b[i] == 2){
            if(que[2].empty()){
                printf("%d%c",-1,i==m-1?'\n':' ');
                continue;
            }else{
                bool flag = false;
                while(!que[2].empty()){
                    node no = que[2].top();que[2].pop();
                    if(vis[no.id]) continue;
                    else{
                        flag = true;
                        vis[no.id] = true;
                        printf("%d%c",no.p,i==m-1?'\n':' ');
                        break;
                    }
                }
                if(!flag){
                    printf("%d%c",-1,i==m-1?'\n':' ');
                }
            }
        }else if(b[i] == 3){
            if(que[3].empty()){
                printf("%d%c",-1,i==m-1?'\n':' ');
                continue;
            }else{
                bool flag = false;
                while(!que[3].empty()){
                    node no = que[3].top();que[3].pop();
                    if(vis[no.id]) continue;
                    else{
                        flag = true;
                        vis[no.id] = true;
                        printf("%d%c",no.p,i==m-1?'\n':' ');
                        break;
                    }
                }
                if(!flag){
                    printf("%d%c",-1,i==m-1?'\n':' ');
                }
            }
        }
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值