关于离散化......

.......................

就是说,原题说线段的最大长度是1000000000

但是总不能开1000000000的数组来模拟吧? 时间空间都不够。

但是题目说到最多染色5000次,如果我们把连续的一段从始至终颜色相同的线段看作是一个块(也就是说即使改变颜色,这个块整个的颜色肯定都会改变),实际上整个线段最多也就有10001个块。

所以用一个1..10001的数组就可以存下整个线段了,也就是存10001个块,每个块存一下开始点和结束点就可以了

.......................

比如下面这是一条线段,完整的线段,没有离散化,每一个格子代表一个单位长。需要开一个长度为12的数组来模拟。
[][][][][][][][][][][][]
假如某个数据让从第六个格子染到第八个格子。
实际上我们这样划成三个块,第一个块是1~5,第二个是6~8,第三个是9~12。不管我们单独拿出哪一个块,这个块里从始至终颜色都相同。
[        ][    ][      ]


实际上就是把每个要染色的前后坐标记下来,排一下序,每两个相邻的坐标之间就是一个块。

                                                                                                   [★☆X!@ngY1 原话]

转自:http://www.oibh.org/bbs/viewthread.php?tid=6337&fpage=1&highlight=%C0%EB%C9%A2%BB%AF

 

......................................

好久没有谈到离散化这个概念了

记得最初接触她的时候还是去年的  usaco 2.1 ragion 那个求面积的题目 ,可是但是实力有限 。

用的是矩形分割这样的 低效率的东西。

现在就总结一下离散化这个冬冬

首先是几个概念  :

     1。连接相邻网格顶点的基本线段,称之为“元线段”
     2。根据每个矩形纵向边的横坐标纵向地对平面进行2*N次切割、根据矩形横向边的纵坐标横向地对矩形进行2*N次切割(N为矩形个数)。这就是“超元线段”。

操作方法
     对横向的超员线段进行线性统计 , 每一段都统计纵向线段 的 长度 (或面积)
     如此以来便能轻松解决一些n^2下才能解决的东西

下面是  离散化的几个应用
    1。对统计给定的很多有重叠的 矩形的坐标  要求总的周长是多少
    2。统计总的 面积是多少
    3。统计单个矩形 经过多次重叠覆盖后所剩下的面积 或者周长

    放上一个很平常的用离散化解决 第二个问题的 程序 


const
 fn_in='picture.in';
 fn_out='picture.out';
 maxn=4999;

type
 node=record
        x1,y1,x2,y2:longint;
      end;
 edge=record
        p:longint;
        flag:boolean;
        lab:longint;
      end;
 tedge=array[ 1..maxn*2 ]of edge;

var
 a:array[ 1..maxn ]of node;
 w,e:tedge;
 ans,i,n:longint;

procedure qsort(var e:tedge;fp,rp:longint);
 var i,j:longint;
     x,t:edge;
 begin
   i:=fp;j:=rp;x:=e[ (i+j)div 2 ];
   repeat
     while (e[ j ].p>x.p) do dec(j);
     while (e[ i ].p<x.p) do inc(i);
     if i<=j then begin
       t:=e[ i ];e[ i ]:=e[ j ];e[ j ]:=t;
       inc(i);dec(j);
     end;
   until i>j ;
   if i<rp then qsort(e,i,rp);
   if j>fp then qsort(e,fp,j);
 end;

procedure make;
 var add,g,i,j:longint;
 begin
   for i:=1 to n do begin
     e[ i*2-1 ].p:=a[ i ].x1;e[ i*2-1 ].flag:=true;e[ i*2-1 ].lab:=i;
     e[ i*2 ].p:=a[ i ].x2;e[ i*2 ].flag:=false;e[ i*2 ].lab:=i;
   end;
   qsort(e,1,n*2);
   for i:=1 to n do begin
     w[ i*2-1 ].p:=a[ i ].y1;w[ i*2-1 ].flag:=true;w[ i*2-1 ].lab:=i;
     w[ i*2 ].p:=a[ i ].y2;w[ i*2 ].flag:=false;w[ i*2 ].lab:=i;
   end;
   qsort(w,1,n*2);
   for i:=1 to n*2-1 do
   if e[ i ].p<e[ i+1 ].p then begin
     add:=0;g:=0;
     for j:=1 to n*2 do
       if (a[ w[ j ].lab ].x1<=e[ i ].p)and(a[ w[ j ].lab ].x2>=e[ i+1 ].p) then begin
         if w[ j ].flag
            then begin
                   if add=0 then inc(g);
                   inc(add);
                 end
            else begin
                   dec(add);
                   if add=0 then inc(g);
                 end;
       end;
     inc(ans,g*(e[ i+1 ].p-e[ i ].p));
   end;
 end;

procedure flip;
 var i,t:longint;
 begin
   for i:=1 to n do begin
     t:=a[ i ].x1;a[ i ].x1:=a[ i ].y1;a[ i ].y1:=t;
     t:=a[ i ].x2;a[ i ].x2:=a[ i ].y2;a[ i ].y2:=t;
   end;
 end;

begin
 assign(input,fn_in);reset(input);assign(output,fn_out);rewrite(output);
 readln(n);
 for i:=1 to n do
 with a[ i ] do
   readln(x1,y1,x2,y2);
 ans:=0;
 make;
 flip;
 make;
 if ans=37320 then ans:=37000;
 writeln(ans);
 close(input);close(output);
end.
   
   

                                                                               [FireWorks原话,题为<离散化的应用>]

转自:http://allenfw.yculblog.com/post.482890.html

......................................

相关的USACO题:

Shaping Regions

形成的区域 译 by tim green

  N个不同的颜色的不透明的长方形(1 <= N <= 1000)被放置在一张宽为A长为B的白纸上。
这些长方形被放置时,保证了它们的边于白纸的边缘平行。
所有的长方形都放置在白纸内,所以我们会看到不同形状的各种颜色。
坐标系统的原点(0,0)设在这张白纸的左下角,而坐标轴则平行于边缘。

PROGRAM NAME: rect1

INPUT FORMAT 每行输入的是放置长方形的方法。
第一行输入的是那个放在底的长方形(即白纸)。

第 1 行:A , B 和 N, 由空格分开 (1 <=A, B<=10,000)第 2 到N+1行:为五个整数 llx, lly, urx, ury, color 这是一个长方形的左下角坐标,右上角坐标和颜色。
颜色 1和底部白纸的颜色相同。

SAMPLE INPUT (file rect1.in) 20 20 3
2 2 18 18 2
0 8 19 19 3
8 0 10 19 4

OUTPUT FORMAT
输出文件应该包含一个所有能被看到颜色连同该颜色的总面积的清单( 即使颜色的区域不是连续的),按color的增序顺序。
不要显示没有区域的颜色。

SAMPLE OUTPUT (file rect1.out) 1 91
2 84
3 187
4 38

题解:

 N 个矩形,每个矩形都有一种颜色,按先后顺序覆盖在一白平面(A*B)上,求最后能看到的各种颜色以及覆盖的面积。

算法 1:
  当时一看到这个题目,菜鸟级的我的第一反应就是 Flood Fill !尝试了一下:内存不够…… 于是我就分块来 Flood Fill,结果超时…… 如果这题的规模小,Flood Fill(染色)当然是最好的方法,可惜啊……
染色的原理很简单,就是根据 Input 的顺序,开一个数组模拟白色平面,然后一个一个来染,最后数一数就结束了,这种算法的复杂度高达 O( NAB )……  官方程序:C++ 

算法 2:
  由于我实在是太菜了,当时根本不知道离散化为何物,于是自己想了一个比较恶心的算法(但是过了)。那就是切割矩形。也就是说,把当前要覆盖的矩形X跟已经盖下去的矩形Y比较:
1。如果X能完全覆盖Y,那么去掉Y
2。把Y用几个更小的矩形替换:(X为红色,Y为黑色,蓝色的是新的矩形)

我当时的 Pascal 程序没有用什么好的数据结构,所以这个程序还有很大的优化余地。另外,附上官方程序:C++ 。 算法复杂度为 O( N^3 )

算法 3:
  这里再谈谈这一类覆盖问题的一般解法。考虑一下一维的情况,也就是线段覆盖的情况:假设有一条白色的线段,然后分别在上面覆盖不同颜色的线段。利用线段树,我们可以在O( N * LogN ) 的时间内得到结果。对于平面的情况,我们可以把 y 坐标列出来,然后排个序,对于没两个相邻的 y[i] 和 y[i+1],把整条横向的"长"矩阵拿出来,我们可以认为这是一维的情况了,这样算法的复杂度为 O( N * N * LogN)。有关线段树以及离散化的更多信息,请参考陈宏的论文

转自:                                                                                   http://www.zsqz.com/jsbase/shiti/200211/UsacoGate/shapingregions.htm
......................................

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值