就是说,原题说线段的最大长度是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: |
算法 2: |
算法 3: |
转自: http://www.zsqz.com/jsbase/shiti/200211/UsacoGate/shapingregions.htm
......................................