ural 1303 Minimal Coverage(贪心)

链接:

http://acm.timus.ru/problem.aspx?space=1&num=1303

按照贪心的思想,每次找到覆盖要求区间左端点时,右端点最大的线段,然后把要求覆盖的区间改为这个右端点到M这个区间。依次类推下去,这样的话就只需要扫一遍就可以找去来。

要做的预备工作就是将线段按照左端点的升序排序就可以了。

它的时间复杂度就是O(n)

代码一直WA,望大神指教

 

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<string.h>
 4 #include<map>
 5 #include<vector>
 6 #include<set>
 7 #include<stack>
 8 #include<queue>
 9 #include<algorithm>
10 #include<cmath>
11 #include<stdlib.h>
12 using namespace std;
13 #define MAX(a,b) (a > b ? a : b)
14 #define MIN(a,b) (a < b ? a : b)
15 #define MAXN  200005
16 #define INF 1000000007
17 #define mem(a) memset(a,0,sizeof(a))
18 #define judge(i) (ma[i].l<=L && ma[i].r>=L && ma[i].l != ma[i].r)//判断是否覆盖了点L
19 
20 struct node{int l,r;}ma[MAXN];
21 int ans[MAXN];
22 int M,N,T;
23 int L;
24 
25 int cmp(node a,node b)
26 {
27     if(a.l != b.l)return a.l<b.l;
28     else return a.r<b.r;
29 }
30 
31 
32 
33 int find_index(int s,int &i)//找到覆盖了点L而且右端点最大的点,并返回;
34                             //同时将后面要覆盖的点设置为它的右端点
35 {
36     i = s;
37     int e = s,endd = ma[i].r;
38     while(i < N && judge(i) )
39     {
40         if(ma[i].r > endd)
41         {
42             endd = ma[i].r;
43             e = i;
44         }
45         i++;
46     }
47     L = endd;//endd就是满足覆盖条件下的最大的右端点
48             //并将其设置为下次比较的左端点
49     return e;//返回此次的线段的下标
50 }
51 
52 int main()
53 {
54     while(~scanf("%d",&M))
55     {
56         N=0;
57         int i;
58         mem(ans);
59         while(scanf("%d%d",&ma[N].l, &ma[N].r) && (ma[N].l || ma[N].r))
60         {
61             if(ma[N].r <=0 || ma[N].l>=M)ma[N].l = ma[N].r = INF;//吧在要求区间两端之外的线段去掉
62                   //吧它的左右端点值赋值为INF,这样的话排序时自然就会到最后方,也就相当于不用考虑
63             N++;
64         }
65         sort(ma,ma+N,cmp);
66 
67         L = 0;//最初要被覆盖的点是0
68         int num = 0;
69         for(i=0;i<N;i++)
70         {
71             int t = i+1;//将t设置为i+1,如果下面的judge成功,就会进入函数的while中,那么i会++,如果不成功,t=i+1
72             if(judge(i))   ans[num++] = find_index(i,t);
73             i = t-1;//由于t相当于多+了1,所以-1
74             if(L >= M)break;//一旦找到,就退出循环
75         }
76         if(L < M)printf("No solution\n");
77         else
78         {
79             printf("%d\n",num);
80             for(i=0;i<num;i++)
81             {
82                 printf("%d %d\n",ma[ans[i]].l,ma[ans[i]].r);
83             }
84         }
85     }
86     return 0;
87 }

 

 

 

 

 

 

转载于:https://www.cnblogs.com/gj-Acit/p/3207666.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值