zoukankan      html  css  js  c++  java
  • 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
    ");
    77         else
    78         {
    79             printf("%d
    ",num);
    80             for(i=0;i<num;i++)
    81             {
    82                 printf("%d %d
    ",ma[ans[i]].l,ma[ans[i]].r);
    83             }
    84         }
    85     }
    86     return 0;
    87 }
  • 相关阅读:
    cocos2d与cocos2d-X中的draw和update
    poj1673
    hdu2128之BFS
    常用的js效验
    OMCS的语音视频带宽占用
    UML类图详细介绍
    [置顶] 获取激活码,激活myeclipse
    CBO学习----03--选择率(Selectivity)
    notepad++ 文件对比插件
    永远不要在Linux 执行的 10 个最危险的命令
  • 原文地址:https://www.cnblogs.com/gj-Acit/p/3207666.html
Copyright © 2011-2022 走看看