题解 P2161 【[SHOI2009]会场预约】
一个非常简单的STL做法(非常好想,代码很短)
题意已经暗示的很明确要你使用平衡树了,但本蒟蒻太懒,不想打平衡树,于是便考虑偷懒用STL(还不是是因为太弱)
我们可以用一个有两个元素的结构体来保存一个预约,如下:
struct Plan{
int l,r; //l,r分别表示预约开始,结束的时间
};
首先考虑A操作,由于STL的set有相同元素只保留一个的特性,因此我们不难想到令有冲突的预约相等,这样我们就可以很方便的用.find()这个函数来完成A操作了。
怎么令它们相等呢?
其实也很简单,由于使用自定义数据类型的set要重载运算符,因此我们可以这样:
struct Plan{
int l,r;
bool operator <(const Plan &rhs)const{
return r<rhs.l;
}
};
这样对于两个Plan类型的结构体a,b来说,a<b就代表a完全在b的左边,a>b就代表a完全在b的右边,a==b就代表a与b有冲突(有重叠部分)
对于B操作,直接输出set里元素的个数就好了
于是我们就可以快乐的A掉这道题了
有了上面的思路,代码也不难写出:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<set>
using namespace std;
struct Plan{
int l,r;
bool operator <(const Plan &rhs)const{
return r<rhs.l;
}
};
int T;
set<Plan> s;
int main(){
cin>>T;
while(T--){
char c; scanf(" %c",&c); //空格可以防止读入无效字符
if(c=='A'){
int l,r,cnt=0; scanf("%d %d",&l,&r);
Plan tmp=(Plan){l,r};
//删掉与该预约冲突的预约,并统计个数
set<Plan>::iterator it=s.find(tmp);
while(it!=s.end()){
++cnt; s.erase(it);
it=s.find(tmp);
}
s.insert(tmp);
printf("%d\n",cnt);
}
else{
printf("%d\n",s.size());
}
}
return 0;
}
AC记录:R14872282 评测详情