[矩形切割][离散化][usaco3.1.4]Shaping Regions
来源:互联网 发布:九九网络 编辑:程序博客网 时间:2024/05/08 03:14
译 by tim green
目录
[隐藏]- 1 描述
- 2 格式
- 3 SAMPLE INPUT
- 4 SAMPLE OUTPUT
- 5 INPUT EXPLANATION
- 6 HINTS(谨慎地使用它们!)
[编辑]描述
N个不同的颜色的不透明的长方形(1 <= N <= 1000)被放置在一张横宽为A竖长为B的白纸上。 这些长方形被放置时,保证了它们的边与白纸的边缘平行。 所有的长方形都放置在白纸内,所以我们会看到不同形状的各种颜色。 坐标系统的原点(0,0)设在这张白纸的左下角,而坐标轴则平行于边缘。
[编辑]格式
PROGRAM NAME: rect1
INPUT FORMAT:
(file rect1.in)
按顺序输入放置长方形的方法。第一行输入的是那个放在底的长方形(即白纸)。
第 1 行: A , B 和 N由空格分开 (1 <=A, B<=10,000)
第 2 到N+1行: 为五个整数 llx, lly, urx, ury, color 这是一个长方形的左下角坐标,右上角坐标(x+1,y+1)和颜色。
颜色 1和底部白纸的颜色相同。 (1 <= color <= 2500)
OUTPUT FORMAT:
(file rect1.out)
输出且仅输出所有能被看到颜色,和该颜色的总面积(可以由若干个不连通的色块组成),按color增序排列。
[编辑]SAMPLE INPUT
20 20 32 2 18 18 20 8 19 19 38 0 10 19 4
.......
[编辑]SAMPLE OUTPUT
1 912 843 1874 38
[编辑]INPUT EXPLANATION
请注意:被(0,0)和(2,2)所描绘的是2个单位宽、2个单位高的区域
这里有一个示意图输入:
1111111111111111111133333333443333333331333333334433333333313333333344333333333133333333443333333331333333334433333333313333333344333333333133333333443333333331333333334433333333313333333344333333333133333333443333333331333333334433333333311122222244222222221111222222442222222211112222224422222222111122222244222222221111222222442222222211112222224422222222111111111144111111111111111111441111111111
'4'在(8,0)与(10,19)形成的是宽为2的区域,而不是3.(也就是说,4形成的区域包含(8,0)和(8,1) ,而不是(8,0)和(8,2)) 。
方法一:矩形切割
提交了两次,因为面积为零的表示不存在,不能输出。
两天尝试了自己研究矩形切割的算法而失败。
我的思路建立在线性时间解决问题上,即由上到下依次求并。
我的两种设想:
1、完全分类讨论,两个矩形有17种相对位置关系,每种位置关系切割出的矩形数目不同,显然这种方法很难实现。
2、双进程递归,两个进程交替进行,即横竖交替,显然这样的方法速度会有很大影响。
都不能实现。现在常用的方法则摒弃了线性,退而求其次,O(n^2),事实证明能过所有数据,不知为什么。。
外层循环只考虑一个矩形,被上层的所有矩形切割后的结果,并集的实现则累加切割后的小矩形即可。
这样的话,进行了几次外层循环就得到了几个矩形的并集。
用S(A)表示A的面积。则有
S(A ∩ CuB) = S(A∪B) - S(B)
/*ID: wuyihao1LANG: C++TASK: rect1*/#include <cstdio>#include <algorithm>using std::sort;int lx[10010];int rx[10010];int ly[10010];int ry[10010];int col[10010];int col2[10010];int ans[10010];int n;int rec;void rect(int i,int llx,int lly,int rrx,int rry){while (i<n+1 && (llx>rx[i]||rrx<lx[i]||lly>ry[i]||rry<ly[i])) i ++;if (i == n+1) { rec += (rrx-llx)*(rry-lly); return; }if (lx[i]>llx){rect(i+1,llx,lly,lx[i],rry);llx=lx[i];}if (rx[i]<rrx){rect(i+1,rx[i],lly,rrx,rry);rrx=rx[i];}if (ly[i]>lly){rect(i+1,llx,lly,rrx,ly[i]);}if (ry[i]<rry){rect(i+1,llx,ry[i],rrx,rry);}}int main(){freopen("rect1.in","r",stdin);freopen("rect1.out","w",stdout);scanf("%d%d%d",rx+1,ry+1,&n);lx[1] = ly[1] = 0;col2[1] = col[1] = 1;n ++;for (int i=2;i<n+1;i++){scanf("%d%d%d%d%d",lx+i,ly+i,rx+i,ry+i,col+i);col2[i] = col[i];}ans[col[n]] = rec = (ry[n]-ly[n])*(rx[n]-lx[n]);for (int i=n-1;i>0;i--){int last = rec;rect(i+1,lx[i],ly[i],rx[i],ry[i]);ans[col[i]] += rec-last;}sort(col2+1,col2+n+1);col2[0] = -0x3f3f3f3f;for (int i=1;i<n+1;i++){if (col2[i] != col2[i-1] && ans[col2[i]]>0){printf("%d %d\n",col2[i],ans[col2[i]]);}}return 0;}
方法二:离散化+倒序染色
交了两次才过。因为离散化后,横边和纵边都为2N,而不是N。
注意跳过上下或左右相等的所有情况,这样的矩形不存在。这样对速度略有优化。
/*ID: wuyihao1LANG: C++TASK: rect1*/#include <cstdio>#include <algorithm>using std::sort;int a;int b;int n;int hr[200010];int vt[200010];int lx[1010];int ly[1010];int rx[1010];int ry[1010];int col[1010];int ans[2510];int main(){freopen("rect1.in","r",stdin);freopen("rect1.out","w",stdout);scanf("%d%d%d",&a,&b,&n);for (int i=0;i<n;i++){scanf("%d%d%d%d%d",&hr[i<<1],&vt[i<<1],&hr[(i<<1)+1],&vt[(i<<1)+1],&col[i+1]);lx[i+1] = hr[i<<1];ly[i+1] = vt[i<<1];rx[i+1] = hr[(i<<1)+1];ry[i+1] = vt[(i<<1)+1];}n ++;col[0] = 1;lx[0] = 0;ly[0] = 0;rx[0] = a;ry[0] = b;hr[(n-1)<<1] = 0;vt[(n-1)<<1] = 0;hr[((n-1)<<1)+1] = a;vt[((n-1)<<1)+1] = b;sort(hr,hr+(n<<1));sort(vt,vt+(n<<1));for (int i=1;i<(n<<1);i++){if (hr[i]==hr[i-1])continue;for (int j=1;j<(n<<1);j++){if (vt[j]==vt[j-1])continue;for (int k=n-1;k>-1;k--){if (hr[i-1]>=lx[k] && hr[i]<=rx[k]&&vt[j-1]>=ly[k] && vt[j]<=ry[k]){ans[col[k]] += (hr[i]-hr[i-1])*(vt[j]-vt[j-1]);break;}}}}for (int i=1;i<2501;i++){if (ans[i])printf("%d %d\n",i,ans[i]);}return 0;}
- [矩形切割][离散化][usaco3.1.4]Shaping Regions
- USACO Shaping Regions,难题,离散化,矩形切割,逆序染色
- ural1147(Shaping Regions)矩形切割
- usaco Section 3.1 Shaping Regions -- 矩形切割
- 【矩形切割】Shaping Regions形成的区域
- USACO 6.2.3 shaping regions 矩形切割
- [URAL 1147][USACO rect1]Shaping Regions(矩形切割)
- 离散化 usaco Shaping Regions (rect1)
- 【USACO3.1.4】形成的区域 二维线段树/离散化/矩形切割/浮漂法 【线段树方法以后写】
- USACO / Shaping Regions (矩形分割)
- USACO Shaping Regions(二维线段树做法 原USACO3.1.4?还是3.4.1?)
- USACO Section 3.1 Shaping Regions - 矩阵切割..
- [USACO3.1.4] 形成的区域 - 线段树/矩形切割
- Shaping Regions
- USACO 3.1 Shaping Regions
- 【模拟】【USACO】Shaping Regions
- usaco Shaping Regions
- Shaping Regions解题报告
- a标签中正确的使用text-indent
- linux中驱动异步通知应用程序的方法
- 定时器 LED 闪烁功能
- 在android的spinner中,实现key(id)和Value的取值
- Hibernate常用Annotation标签说明
- [矩形切割][离散化][usaco3.1.4]Shaping Regions
- shell中特殊字符的意思
- MFC Problem Processing
- 一个高效率的分页存储过程
- vimdiff
- lifetype
- 通用环境安装命令
- 如何架构一个ios项目 个人经验总结
- printf()与scanf()