uva 11020 Efficient Solutions(multiset)

题意:给出n个人的属性(a,b),当A(a,b)与B(a',b')存在关系:(a<a'&&b<=b')||(a<=a'&&b<b')就说A比B占优势,否则,两人都存在优势。问:每输入一个人的信息,计算当前占优势的人的个数。

分析:容易想到以坐标形式在一个平面图上表示每个人的信息,那么以上的条件关系式就转变为,当一个点的左下方(可以是正左、正下)有一个点,那么该点失去优势。关键是明确当一个点失去优势后,就不再可能重新获得优势。那么只要维护所有有优势的人群即可——选择一个合适的数据结构。

    我们选择multiset(可重集)来处理,这里要注意的是存在属性完全相同的两个人。这里使用multiset,是利用它自动排序和可重两个特点。当把一个人(x1,y1)加入集合,只要与其左侧(x2<x1||(x2==x1&&y2<y1))作比较,就可以判断是否有优势;若加入集合,只要向右(x2>x1)查找,所有(y2>y1)的点(x2,y2)都失去优势,从集合中删除。

注意:若左侧没有点it==s.begin(),必然可以加入。

 1 #include<cstdio>
 2 #include<set>
 3 using namespace std;
 4 
 5 struct P{
 6       int x,y;
 7       bool operator < (const P& rhs)const {
 8             return x<rhs.x||(x==rhs.x&&y<rhs.y);
 9       }
10  };
11 
12 multiset<P>s;
13 multiset<P>::iterator it;
14 
15 int main()
16 {
17       int T,n;
18       scanf("%d",&T);
19       for(int k=1;k<=T;k++)
20       {
21             if(k!=1)puts("");
22             printf("Case #%d:\n",k);
23             s.clear();
24 
25             scanf("%d",&n);
26             while(n--)
27             {
28                   int x,y;
29                   scanf("%d%d",&x,&y);
30                   P e=(P){x,y};
31                   it=s.lower_bound(e);
32                   if(it==s.begin()||(--it)->y>y){
33                         s.insert(e);
34                         it=s.upper_bound(e);
35                         while(it!=s.end()&&it->y>=y){
36                               s.erase(it++);
37                         }
38                   }
39                   printf("%d\n",s.size());
40             }
41       }
42       return 0;
43 }
View Code

 

posted @ 2013-10-16 15:03  Thousand Sunny  阅读(245)  评论(0编辑  收藏  举报