USACO-Shaping Regions
来源:http://www.nocow.cn/index.php/Translate:USACO/rect1
很明显灌水法是行不通的。
什么是灌水法?就是把每一个矩形都标记一遍,最后扫描整个大矩阵,算法的时间复杂度是O(N^2),看数据规模就知道肯定死翘翘了。
这题我选用了漂浮法,也称碰撞法。
漂浮法在nocow上是这样描述的:
漂浮法
以逆序来进行放置,即n to 1。逆序的好处在于放置一个矩形后,俯视看到的就是最终俯视该矩形应该看到的。因为挡着它的矩形在之前已经放置好了,所以可直接统计,为递归创造了条件。每放一个矩形,可以想象成将其扔入一密度很大的海水底部,海分成了n层,然后矩形开始向上浮。在上浮过程中若碰撞到其他的矩形则断裂成几个小矩形,继续上浮,直到浮出水面。于是想到用个递归来模拟上浮过程。
下面是我的个人见解:
我们先考虑简单的情况:
情况1 情况2 情况3 情况4
这是最简单的4种遮挡情况,而复杂的遮挡情况总可以通过矩阵分割得到上面几种情况,举个例子:
对于这样的遮挡,我们可以这样分割:
把这种情况看成是情况1进行处理,先处理蓝色的部分,对于右边部分进行递归,按照情况3进行处理,其他所有的遮挡情况均可类似分割。
值得注意的是以下的遮挡情况:
我们需要进行如下切割:
这个需要对切割时的判断条件进行精确的描述。
到此,我们已经找到了处理遮挡的一般方法,下面进行总结:
1.我们可以从最底部,也可以从最顶部开始处理每个矩阵,这里采用从最底部的矩阵开始处理;
2.枚举每一个矩阵,与当前处理的矩阵进行遮挡处理,这个遮挡处理的递归终止条件是分割的小矩阵已处于最顶部;
3.统计每个颜色的面积。
给出核心代码:
void cover(int lx,int ly,int ux,int uy,int col,int k) //(lx,ly)左下角,(ux,uy)右上角,下面的数组类似 { while (k<=n && (llx[k]>=ux || urx[k]<=lx || lly[k]>=uy || ury[k]<=ly)) k++; if (k>n) { S[col]+=((ux-lx)*(uy-ly)); return; } if (lx<=llx[k]) { cover(lx,ly,llx[k],uy,col,k+1); lx=llx[k]; } //情况1 if (ly<=lly[k]) { cover(lx,ly,ux,lly[k],col,k+1); ly=lly[k]; } //情况3 if (ux>=urx[k]) { cover(urx[k],ly,ux,uy,col,k+1); ux=urx[k]; } //情况2 if (uy>=ury[k]) { cover(lx,ury[k],ux,uy,col,k+1); uy=ury[k]; } //情况4 }
其实对于每个情况都有几种判断方法,比如情况1,可以写(lx<=llx[k]),也可以写成(ux<=urx[k]),还有(llx[k]<=ux),但是后面的两种判断并不准确,比如说(llx[k]<=ux)也可以用来表示情况2,所以这里的几个条件一定要重视。
更具体的代码:
/* ID:ay27272 PROG:rect1 LANG:C++ */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define NN 1005 int llx[NN],lly[NN],urx[NN],ury[NN],color[NN]; int S[NN]; int n; void cover(int lx,int ly,int ux,int uy,int col,int k) { while (k<=n && (llx[k]>=ux || urx[k]<=lx || lly[k]>=uy || ury[k]<=ly)) k++; if (k>n) { S[col]+=((ux-lx)*(uy-ly)); return; } if (lx<=llx[k]) { cover(lx,ly,llx[k],uy,col,k+1); lx=llx[k]; } if (ly<=lly[k]) { cover(lx,ly,ux,lly[k],col,k+1); ly=lly[k]; } if (ux>=urx[k]) { cover(urx[k],ly,ux,uy,col,k+1); ux=urx[k]; } if (uy>=ury[k]) { cover(lx,ury[k],ux,uy,col,k+1); uy=ury[k]; } } int main() { freopen("rect1.in","r",stdin); freopen("rect1.out","w",stdout); int X,Y,max_color=0; cin>>X>>Y>>n; for (int i=1;i<=n;i++) { scanf("%d%d%d%d%d",&llx[i],&lly[i],&urx[i],&ury[i],&color[i]); if (color[i]>max_color) max_color=color[i]; } memset(S,0,sizeof(S)); for (int i=1;i<=n;i++) cover(llx[i],lly[i],urx[i],ury[i],color[i],i+1); S[1]=X*Y; for (int i=2;i<=max_color;i++) S[1]-=S[i]; for (int i=1;i<=max_color;i++) if (S[i]) cout<<i<<" "<<S[i]<<endl; return 0; }
USACO-Shaping Regions相关推荐
- usaco Shaping Regions
这就是usaco 前面的windows area的变形. /* ID:jinbo wu TASK:rect1 LANG:C++ */ #include<iostream> #include ...
- USACO Shaping Regions(离散化)
记录一下我一直很怕做的一道离散化题.都卡了大半个月了,今天终于过了.这种离散化的题就一个恶心,不然早就啃过去了. 代码如下: View Code 1 /* 2 ID: lyon.ly1 3 LANG: ...
- ural1147 Shaping Regions
Shaping Regions Time limit: 0.5 second Memory limit: 64 MB N opaque rectangles (1 ≤ N ≤ 1000) of var ...
- usaco Section 3.1 Shaping Regions -- 矩形切割
听说这道题用矩形切割做,于是学习了2004薛矛的oi论文. 我的做法是:弄一个白纸集合,开始里面只有一张白纸(0,0) (A,B).然后把输入的N个矩形倒序地,每一个都与白纸集合中的所有白纸依次切割. ...
- 算法学习之——矩形切割思想
算法学习之--矩形切割思想 MPS [定义 Define] 对于求解若干个矩形的面积的交集 ...
- 博客模板:xiu-v7-0阿里百秀主题-去域名限制
<![endif]--> 公交车司机终于在众人的指责中将座位让给了老太太 </div> </div> </figure> 白嫖博客 你已登录为 : 13 ...
- 训练技巧《Must Know Tips/Tricks in Deep Neural Networks (by Xiu-Shen Wei)》学习笔记
原 <Must Know Tips/Tricks in Deep Neural Networks (by Xiu-Shen Wei)>学习笔记 2019年01月19日 22:20:40 咸 ...
- 当前进度,已学算法,未做题目
当前学习 CSP-S备战中 已学算法 从初一开始算起,按照时间顺序排序 算法简称 算法全称 备注 无 高精度 比较基础的算法 d e p t h f i r s t s e a r c h ( D F ...
- USACO 2020~2021 February Contest GOLD 题解(3)
USACO 2020~2021 二月黄金组 题解(3) 3. Count The Cows As is typical, Farmer John's cows have spread themselv ...
- [LeetCode] 130. Surrounded Regions Java
题目:Given a 2D board containing 'X' and 'O' (the letter O), capture all regions surrounded by 'X'. A ...
最新文章
- 皮一皮:六神终于出奶茶了!
- 初学者学python看什么书-python初学者看什么书
- MATLAB 数组运算
- 正则化方法:防止过拟合,提高泛化能力
- PyTorch 实现经典模型6:RCNN (Fast RCNN, Faster RCNN)
- java编程pig编码_Pig编程指南.pdf
- Codeforces 1025F Disjoint Triangles (计算几何)
- linux网络编程之posix 线程(四):posix 条件变量与互斥锁 示例生产者--消费者问题
- avalon2框架应用注意事项
- Go 触发 GC 的时机有哪些?能手动触发吗?
- rpm包制作介绍及实战操作讲解01(学生分享)
- 充满艺术范儿!艺术感在线的界面欣赏
- 怎么把pdf的背景去掉_PDF试卷有页眉还有水印,打印出来一片花,怎么办?
- 微信公众号关闭iOS端虚拟支付业务;苹果「Apple 登录」存安全漏洞;谷歌推迟发布Android 11 Beta| 极客头条...
- python文件操作笔记
- 2021百强县市名单
- Rust: HDF5文件的处理探索(to be continued.......)
- 【20点埃及 VS 乌拉圭/23点摩洛哥vs 伊朗】快看人工只能预测结果(附最全赛事时间表)...
- java 获取年和季度_java获取当前时间的年周月季度等的开始结束时间
- 一只程序员的成长与思考