Shaping Regions Usaco 递归分治
2016-06-10 14:32
218 查看
传送门
这题坑了我好久
貌似扫描线不好写啊,我们来看这题特有的性质。由于放置先后所以总是能够覆盖之前的。如果用暴力话,我们需要每一次将范围内所有点打上标记而且即使注意到覆盖,时间复杂度仍然不会好多少出数据的人也不傻他们很认真卡你(例如每一个矩形都恰好覆盖整个地图,这时候你就只能打出大写的GG)。然而这也就有了优化的动机,每次的时间主要消耗在“染色”上,如果我们能直接利用矩形面积公式更新答案优化这一过程复杂度就会降低很多。
而我们又要怎么搞呢,考虑递归和分治即可方法
以逆序来进行放置,即 n to 1 。逆序的好处在于放置一个矩形后,俯视看到就是最终该矩形应看到的。因为挡着它在之前已经放置好了,所以可直接统计递归创造条件。每放一个矩形,可以想象成将其扔入密度很大的海水底部分了 n层,然后矩形开始向 上浮。在过程中若碰撞到其他的矩形 则断裂成几个小分别解决他们 ,继续上浮 直到出水面。
于是想到用个递归来模拟上浮过程时间复杂度 O( N^2 )
这题坑了我好久
貌似扫描线不好写啊,我们来看这题特有的性质。由于放置先后所以总是能够覆盖之前的。如果用暴力话,我们需要每一次将范围内所有点打上标记而且即使注意到覆盖,时间复杂度仍然不会好多少出数据的人也不傻他们很认真卡你(例如每一个矩形都恰好覆盖整个地图,这时候你就只能打出大写的GG)。然而这也就有了优化的动机,每次的时间主要消耗在“染色”上,如果我们能直接利用矩形面积公式更新答案优化这一过程复杂度就会降低很多。
而我们又要怎么搞呢,考虑递归和分治即可方法
以逆序来进行放置,即 n to 1 。逆序的好处在于放置一个矩形后,俯视看到就是最终该矩形应看到的。因为挡着它在之前已经放置好了,所以可直接统计递归创造条件。每放一个矩形,可以想象成将其扔入密度很大的海水底部分了 n层,然后矩形开始向 上浮。在过程中若碰撞到其他的矩形 则断裂成几个小分别解决他们 ,继续上浮 直到出水面。
于是想到用个递归来模拟上浮过程时间复杂度 O( N^2 )
#include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> using namespace std; #define N 5000+5 struct data { int x1,y1,x2,y2; int cl;//color data () {} }Li ; int ans ,a,b,n; void up (int x1,int y1,int x2,int y2,int color,int y) { if(x1>=x2||y1>=y2) return ; if(y>n) { ans[color] += (x2-x1)*(y2-y1); return ; } data p=Li[y]; if(y1<p.y1) up(max(p.x1,x1),y1,max(p.x1,x2),min(p.y1,y2),color,y+1); if(y2>p.y2) up(min(x1,p.x2),max(y1,p.y2),min(p.x2,x2),y2,color,y+1); if(x1<p.x1) up(x1,min(p.y2,y1),min(p.x1,x2),min(p.y2,y2),color,y+1); if(x2>p.x2) up(max(p.x2,x1),max(p.y1,y1),x2,max(p.y1,y2),color,y+1); } int main() { cin>>a>>b>>n; for(int i=1;i<=n;i++) scanf("%d%d%d%d%d",&Li[i].x1,&Li[i].y1,&Li[i].x2,&Li[i].y2,&Li[i].cl); Li[0].x1=0; Li[0].y1=0; Li[0].x2=a; Li[0].y2=b; Li[0].cl=1; for(int i=n;~i;--i) up(Li[i].x1,Li[i].y1,Li[i].x2,Li[i].y2,Li[i].cl,i+1); for(int i=1;i<=3000;++i) if(ans[i]) cout<<i<<" "<<ans[i]<<endl; return 0; }
相关文章推荐
- 有关数据库SQL递归查询在不同数据库中的实现方法
- C#中的递归APS和CPS模式详解
- WinForm实现按名称递归查找控件的方法
- C#递归方法实现无限级分类显示效果实例
- 使用SqlServer CTE递归查询处理树、图和层次结构
- C#中的尾递归与Continuation详解
- C#递归实现显示文件夹及所有文件并计算其大小的方法
- php递归创建目录的方法
- PHP递归创建多级目录
- Javascript递归打印Document层次关系实例分析
- C++使用递归方法求n阶勒让德多项式完整实例
- oracle 使用递归的性能提示测试对比
- 使用curl递归下载软件脚本分享
- Perl脚本实现递归遍历目录下的文件
- JavaScript的递归之递归与循环示例介绍
- C# 递归查找树状目录实现方法
- 全排列算法的非递归实现与递归实现的方法(C++)
- php递归列出所有文件和目录的代码
- java递归菜单树转换成pojo对象
- 一个JavaScript递归实现反转数组字符串的实例