来源: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相关推荐

  1. usaco Shaping Regions

    这就是usaco 前面的windows area的变形. /* ID:jinbo wu TASK:rect1 LANG:C++ */ #include<iostream> #include ...

  2. USACO Shaping Regions(离散化)

    记录一下我一直很怕做的一道离散化题.都卡了大半个月了,今天终于过了.这种离散化的题就一个恶心,不然早就啃过去了. 代码如下: View Code 1 /* 2 ID: lyon.ly1 3 LANG: ...

  3. ural1147 Shaping Regions

    Shaping Regions Time limit: 0.5 second Memory limit: 64 MB N opaque rectangles (1 ≤ N ≤ 1000) of var ...

  4. usaco Section 3.1 Shaping Regions -- 矩形切割

    听说这道题用矩形切割做,于是学习了2004薛矛的oi论文. 我的做法是:弄一个白纸集合,开始里面只有一张白纸(0,0) (A,B).然后把输入的N个矩形倒序地,每一个都与白纸集合中的所有白纸依次切割. ...

  5. 算法学习之——矩形切割思想

    算法学习之--矩形切割思想                                                      MPS [定义 Define]   对于求解若干个矩形的面积的交集 ...

  6. 博客模板:xiu-v7-0阿里百秀主题-去域名限制

    <![endif]--> 公交车司机终于在众人的指责中将座位让给了老太太 </div> </div> </figure> 白嫖博客 你已登录为 : 13 ...

  7. 训练技巧《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 咸 ...

  8. 当前进度,已学算法,未做题目

    当前学习 CSP-S备战中 已学算法 从初一开始算起,按照时间顺序排序 算法简称 算法全称 备注 无 高精度 比较基础的算法 d e p t h f i r s t s e a r c h ( D F ...

  9. 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 ...

  10. [LeetCode] 130. Surrounded Regions Java

    题目:Given a 2D board containing 'X' and 'O' (the letter O), capture all regions surrounded by 'X'. A ...

最新文章

  1. 皮一皮:六神终于出奶茶了!
  2. 初学者学python看什么书-python初学者看什么书
  3. MATLAB 数组运算
  4. 正则化方法:防止过拟合,提高泛化能力
  5. PyTorch 实现经典模型6:RCNN (Fast RCNN, Faster RCNN)
  6. java编程pig编码_Pig编程指南.pdf
  7. Codeforces 1025F Disjoint Triangles (计算几何)
  8. linux网络编程之posix 线程(四):posix 条件变量与互斥锁 示例生产者--消费者问题
  9. avalon2框架应用注意事项
  10. Go 触发 GC 的时机有哪些?能手动触发吗?
  11. rpm包制作介绍及实战操作讲解01(学生分享)
  12. 充满艺术范儿!艺术感在线的界面欣赏
  13. 怎么把pdf的背景去掉_PDF试卷有页眉还有水印,打印出来一片花,怎么办?
  14. 微信公众号关闭iOS端虚拟支付业务;苹果「Apple 登录」存安全漏洞;谷歌推迟发布Android 11 Beta| 极客头条...
  15. python文件操作笔记
  16. 2021百强县市名单
  17. Rust: HDF5文件的处理探索(to be continued.......)
  18. 【20点埃及 VS 乌拉圭/23点摩洛哥vs 伊朗】快看人工只能预测结果(附最全赛事时间表)...
  19. java 获取年和季度_java获取当前时间的年周月季度等的开始结束时间
  20. 一只程序员的成长与思考

热门文章

  1. [Linux]桌面和终端的基本操作
  2. What?Poly又双叒叕发新品了?
  3. Load balancer does not have available server for client问题
  4. yami认证显示连接服务器失败,yamip安装教程
  5. 无为才能够无不为-曾仕强
  6. 如何用java实现水仙花数
  7. java 生成pdf文件,添加图片
  8. 虚拟机客户端怎么连接服务器,虚拟机客户端连接服务器
  9. 小米球ngrok 给你惊喜
  10. IIS网站部署步骤(通过域名访问)