糯米

TI DaVinci, gstreamer, ffmpeg
随笔 - 167, 文章 - 0, 评论 - 47, 引用 - 0
数据加载中……

POJ 3168 Barn Expansion 快排

思路:

一开始想到用线段树来做,但是发现坐标范围异常的大,放一个都勉勉强强,更不用说几个了!
想了一下,发现有一个至关重要的条件“不存在覆盖的情况”。
那就没必要用线段树了,因为压根就没必要解决覆盖问题。
可以用一种取巧的方法解决这题。



对于每个矩形,首先把它 y 方向的两条边抽取出来。
对于所有矩形的 y 方向的边,先按照 x 排序,然后按照顶端的 y 坐标排序。



然后对于位于同一 x 坐标的边,找出所有首尾相接或者有交集的边。
那么这些边对应的矩形必定要排除。

对于 x 方向的边,作同样的处理。

排除完之后,剩下的矩形就是可以答案了。

代码 500 多ms。。
#include <stdio.h>
#include 
<stdlib.h>

#define MAX_N 25032

struct node {
    
int barn, start, end, idx;
}
;
struct node vert[MAX_N * 2], hori[MAX_N * 2];
char cannot[MAX_N];
int N, ans;

__inline 
void add_node(struct node *t, int barn, int start, int end, int idx)
{
    t
->barn = barn;
    t
->start = start;
    t
->end = end;
    t
->idx = idx;
}


int cmp_node(const void *a, const void *b)
{
    
struct node *p, *q;
    p 
= (struct node *)a;
    q 
= (struct node *)b;
    
if (p->idx != q->idx)
        
return p->idx - q->idx;
    
return p->start - q->start;
}


__inline 
void disable_barn(int barn)
{
    
if (!cannot[barn]) {
        cannot[barn] 
= 1;
        ans
--;
    }
 
}


__inline 
void calc(struct node *arr, int len)
{
    
int i, idx, end, cnt, first;

    i 
= 0;
    
while (i < len) {
        idx 
= arr[i].idx;
        end 
= arr[i].end;
        first 
= i;
        cnt 
= 0;
        i
++;
        
while (i < len && arr[i].idx == idx && arr[i].start <= end) {
            
if (arr[i].end > end)
                end 
= arr[i].end;
            disable_barn(arr[i].barn);
            cnt
++;
            i
++;
        }

        
if (cnt)
            disable_barn(arr[first].barn);
    }

}


int main()
{
    
int i, top, left, bottom, right;

    freopen(
"e:\\test\\in.txt""r", stdin);

    scanf(
"%d"&N);
    ans 
= N;
    
for (i = 0; i < N; i++{
        scanf(
"%d%d%d%d"&left, &bottom, &right, &top);
        add_node(
&vert[i * 2], i, bottom, top, left);
        add_node(
&vert[i * 2 + 1], i, bottom, top, right);
        add_node(
&hori[i * 2], i, left, right, top);
        add_node(
&hori[i * 2 + 1], i, left, right, bottom);
    }

    qsort(vert, N 
* 2sizeof(vert[0]), cmp_node);
    qsort(hori, N 
* 2sizeof(hori[0]), cmp_node);
    calc(vert, N 
* 2);
    calc(hori, N 
* 2);
    printf(
"%d\n", ans);

    
return 0;
}


posted on 2010-03-18 15:52 糯米 阅读(620) 评论(0)  编辑 收藏 引用 所属分类: POJ


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理