codeforces 556d


觉得可以用贪心做,开始想了下因为区间有两个端点,而且位置任意,有点不好处理。后来就想先以一个端点排序,以另一个端点作为贪心准则。首先对于所有的区间,我们按右端点递增排序。左端点不予考虑。并将所有的数(即桥长)递增排序。然后依次遍历每个区间,然后从剩下的数中找最小的可以满足这个区间的数去满足这个区间,如果找不到则直接输出No。其实就是把按从小到大顺序把桥与可以符合的区间中r最小的那个区间相匹配,这种贪心思路好理解一点,因为这样可以保证剩余的桥长度更大,剩余区间r也更大,而对于l显然长度更大的桥更好,符合贪心思想。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <set>
 4 #include <iostream>
 5 #include <map>
 6 #include <math.h>
 7 #include <algorithm>
 8 #include <vector>
 9 using namespace std;
10 typedef long long ll;
11 const int N = 1000005;
12 const double pi= 3.14159265358979323846264;
13 
14 int n,m,ans[200005];
15 struct st{
16 ll l,r;
17 int id;
18 
19 }isa[200005];
20 struct bge{
21 ll len;
22 int id;
23 }bri[200005];
24 bool cmp1(st a,st b){
25 return a.r<b.r;
26 }
27 bool cmp2(bge a,bge b){
28 return a.len<b.len;
29 }
30 multiset<bge>bridge;//这种set可以从中删除元素
31 
32 bool operator < (bge b1, bge b2)//在multiset的排序中药用到的
33 {
34     return b1.len < b2.len;
35 }
36 bool solve(){
37 bridge.clear();
38 for(int i=1;i<=m;i++)
39     bridge.insert(bri[i]);
40 for(int i=1;i<n;i++){
41     bge val;
42     val.len=isa[i].l;
43     set <bge>::iterator it = bridge.lower_bound(val);//找到bridge集合中第一个小于val.len的点
44      if((*it).len < isa[i].l || (*it).len > isa[i].r) //找不到任何可以满足当前区间的桥
45         {
46             printf("No\n");
47             return false;
48         }
49           ans[isa[i].id] = (*it).id; //用找到的桥满足这个区间
50         bridge.erase(it); //删除当前找到的桥
51 
52 }
53 return true;
54 }
55 int main()
56 {
57     freopen("in.txt","r",stdin);
58 cin>>n>>m;
59 int i;
60 ll pl,pr;
61 ll a,b;
62 for(i=1;i<=n;i++){
63     scanf("%I64d%I64d",&a,&b);
64     if(i!=1){
65         isa[i-1].id=i-1;
66         isa[i-1].l=a-pr;
67         isa[i-1].r=b-pl;
68     }
69     pl=a;
70     pr=b;
71 }
72      for(i=1;i<=m;i++){
73         scanf("%I64d",&bri[i].len);
74         bri[i].id=i;
75      }
76        sort(isa+1,isa+n,cmp1);
77        sort(bri+1,bri+1+m,cmp2);
78    if(solve()){
79     cout<<"Yes"<<endl;
80         for(i=1;i<n-1;i++)
81             printf("%d ",ans[i]);
82         printf("%d\n",ans[n-1]);
83    }
84             return 0;
85 }

 

posted @ 2016-06-29 11:15  十目  阅读(310)  评论(0编辑  收藏  举报