CodeForces - 799B T-shirt buying
题意:有n歌个短袖,每个短袖的前面和后面都有颜色,颜色种类有三种1,2,3,有m个顾客编号从1到m,给出这些顾客喜欢的颜色,从顾客1开始购买衣服,输出每一个带有顾客颜色的衣服且花费最小的钱,没有则输出-1
思路:这个题解法很多,灵活利用基本数的据结构
第一种解法:优先队列,根据3种颜色建立三个优先队列,每次在顾客喜欢颜色的优先队列里取top(),注意每件衣服只能购买一次,需要有个标记标记是否购买
#include<stdio.h>
#include<queue>
#include<string.h>
using namespace std;
const int MAXN=200005;
struct Ts{
int f,b;
int p;
int id;
bool operator<(const Ts &t2) const
{
return p>t2.p;
}
}T[MAXN];
int ans[MAXN];
int num[MAXN];
int main(void)
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&T[i].p);
for(int i=1;i<=n;i++)
scanf("%d",&T[i].f);
for(int i=1;i<=n;i++)
{
scanf("%d",&T[i].b);
T[i].id=i;
}
priority_queue<Ts> p[4];
for(int i=1;i<=n;i++)
{
p[T[i].f].push(T[i]);
p[T[i].b].push(T[i]);
}
int m;
scanf("%d",&m);
int c;
memset(ans,-1,sizeof(ans));
memset(num,0,sizeof(num));
for(int i=1;i<=m;i++)
{
scanf("%d",&c);
while(!p[c].empty())
{
struct Ts temp=p[c].top();
p[c].pop();
if(!num[temp.id])
{
ans[i]=temp.p;
num[temp.id]=1;
break;
}
}
}
for(int i=1;i<=m;i++)
if(i==m) printf("%d\n",ans[i]);
else printf("%d ",ans[i]);
return 0;
}
第二种解法:思路大致是一样的,就是用了set这个数据结构,也是根据三种颜色创建3个集合,每次利用set有序性的性质,不同的是这里不需要标记,直接在集合里删除已经购买的衣服就行了
#include<iostream>
#include<cstdio>
#include<set>
using namespace std;
const int N=2e5+5;
set<int>ms[5];
struct node{
int val,front,back;
}a[N];
int main(void){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i].val;
}
for(int i=1;i<=n;i++){
cin>>a[i].front;
}
for(int i=1;i<=n;i++){
cin>>a[i].back;
}
for(int i=1;i<=n;i++){
ms[a[i].front].insert(a[i].val);
ms[a[i].back].insert(a[i].val);
}
int m;
cin>>m;
for(int i=1;i<=m;i++){
int x;
cin>>x;
if(ms[x].size()==0)
cout<<"-1"<<endl;
else{
int curval=*(ms[x].begin());
cout<<curval<<" ";
for(int i=1;i<=3;i++){
ms[i].erase(curval);
}
}
}
}