用点戳戳(覆盖)的段 - 任何棘手的测试用例?

时间:2016-03-06 06:54:34

标签: greedy

在这个问题中,我想请你破解/破解我的代码,因为我无法想到它没有通过的任何测试用例,但是,它没有通过评分者。

所以这里是问题描述:行上的一组 n 段[l,r],l< = r。我们需要找到最小点数,使每个段至少有一个点并打印这些点的集合。如果该套装有多个版本,请打印任意一个。

如你所见,这里我们有点'戳'段,而不是覆盖最高点的段(我想说我已经搜索并阅读了段 - 覆盖点问题,但它没有帮助)。 / p>

1< = n< = 100; 0< = li< = ri< = 10 ^ 9,0< = i< = n

所以这就是我的所作所为:

  1. 输入段并按其右坐标(即r)的升序对它们进行排序
  2. [l0,r0] - 我的零段,所以 r0 属于答案集。
  3. 对于从 1 last 的段,如果当前段与前一段重叠/相交,除 r0 本身外,我不知道做任何事情,因为当前段中的一个点也属于前一个段并且它已经在答案集中。
  4. 如果没有重叠,或 r-previous 等于 l-current ,我看 l-current 是否大于最后将点添加到答案集并将 r-current 添加到答案集。
  5. 然后我打印结果。
  6. 所以这是代码:

    #include <stdio.h>
    #include <iostream>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    typedef unsigned int point;
    
    struct segment {
        point l;
        point r;
        segment(point l1, point r1): l(l1), r(r1) {}
        bool operator < (const segment &rhs) const { return r < rhs.r; }
    };
    
    
    int main(int argc, const char * argv[]) {
        
        int nSegments = 0;
        
        scanf("%d", &nSegments);
        
        vector<segment> segments;
        
        for(int i = 0; i < nSegments; i++) {
            int l = 0, r = 0;
            scanf("%d %d", &l, &r);
            segments.push_back(segment(l, r));
        }
        
        sort(segments.begin(), segments.end());
        
        vector<point> points;
        
        point right = segments[0].r;
        points.push_back(right);
        
        for (int i = 1; i < nSegments; i++) {
            
            if (segments[i].l < right) {
                right = segments[i].r;
                continue;
            }
            
            if (segments[i].l > points[points.size() - 1]) {
                points.push_back(segments[i].r);
                right = segments[i].r;
                continue;
            }
        }
        
        //for(int i = 0; i < nSegments; i++)
        //    printf("[%d %d]\n", segments[i].a, segments[i].b);
        
        printf("%lu\n", points.size());
        for (int i = 0; i < points.size(); i++) {
            printf("%d ", points[i]);
        }
        return 0;
    }

    我已经考虑过任何可能的测试用例并且通过它们,但是看不出算法有什么问题。

    PS我知道它也不是最好的C ++代码,但现在问题本身就是困扰我。

1 个答案:

答案 0 :(得分:1)

考虑以下几个部分:

l0    r0
|-----|    r1
   |-------|
   l1    |----|
         l2   r2

由于每个段与前一个段重叠,算法将返回集{r0}。如果删除步骤3,算法将返回正确答案{r0, r1}