Codeforces Round #413 B T-shirt buying (STL set)

链接:http://codeforces.com/contest/799/problem/B

题意:

给定n件衣服,对于第i(1<i<=n)件衣服,分别有价格pi,前颜色ai,后颜色bi三个值。然后有m个顺序访问店铺的顾客,每位顾客有一个最喜欢的颜色,只要衣服有一面是他们最喜欢的颜色,他们就会买下这些衣服中最便宜的一件,分别求出每个顾客购买时的价格,如果没有衣服是他们最喜欢的颜色就输出-1。 n,m <= 2e5。

分析:

一开始做的时候看到时间限制3s,直接sort加对于m次询问的O(n)匹配,复杂度为nlogn+m*n,超时。

然后发现这题数据查找的复杂度应该更低才能过, 所以选用了set作为数据结构, 对于set,每次操作都是logn, 平均下来应该是nlogn + mlogn的复杂度,参考了tourist的代码,终于A了。

具体操作是开一个vis去标记哪些衣服被买过。

开3个颜色的set<pair<int,int> s[color],,然后把符合衣服的价钱和编号号作为一对pair插入,这时候set是按pair的first元素排序的。

每次都取x = s[color].begin().second(这个x的含义是,符合条件的最便宜衣服的编号),删除这个颜色set中的这个元素,如果能操作说明里面有元素,否则输出-1。

然后判断这个x代表的衣服是否已经被购买过,如果没有就输出这件价钱,标记为已购买,否则重复取取x = s[color].begin().second,直到输出或者元素被删完,删除其实是因为为了找下一个最小值。

 

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6;
int p[maxn], a[maxn], b[maxn];
int n, m;
set < pair <int, int> > s[7];
bool vis[maxn];
int main()
{
    //freopen("1.txt","r",stdin);
    scanf("%d", &n);
    for(int i = 0; i < n; i++)
    {
        scanf("%d", &p[i]);
    }
    for(int i = 0; i < n; i++)
    {
        scanf("%d", &a[i]);
    }
    for(int i = 0; i < n; i++)
    {
        scanf("%d", &b[i]);
    }
    for(int i = 0; i < n; i++)
    {
        s[a[i]].insert(make_pair(p[i],i));//这个make_pair有点像初始化列表,就是把两个值构成pair然后insert到set中。
        s[b[i]].insert(make_pair(p[i],i));//这是将一对 <价格,编号>的pair插入set,set按first(第一个元素——价格)排序
    }
    scanf("%d", &m);
    memset(vis,0,sizeof(vis));
    while(m--)
    {
        int t,ans = -1;
        scanf("%d", &t);
        while(!s[t].empty())
        {
            int x = (*(s[t].begin())).second;
            s[t].erase(s[t].begin());
            if(vis[x])
            {
                continue;
            }
            vis[x] = 1;
            ans = p[x];
            break;
        }
        printf("%d ", ans);
    }
    puts("");
    return 0;
}

 

原文地址:https://www.cnblogs.com/Jadon97/p/6844931.html