【hihocoder 1249 Xiongnu's Land】线性扫描
2015区域赛北京赛区的三水,当时在赛场上没做出的原因是复杂度分析不正确导致把方法想复杂了。近来复习复杂度分析,觉得不能只是笼统地看渐进复杂度(big-O),更应根据算法的伪码计算真正的以基本操作数为变量的时间复杂度T(n)。
题意:在二维坐标系第一象限中,将一块顶点在原点边长为R的正方形土地用直线x=n一分为二,左侧分给Wei,右侧分给Huo。
土地中包含N个绿洲,每个绿洲是一个矩形,其位置和大小用四元组(L,T,W,H)表示,其中(L,T)为其左上方顶点的坐标,W,H为其宽度和高度。绿洲互不重叠。
求满足以下条件的一条划分直线(直线方程 x=n,0<=n<=R,n取整数):
(1)二人各自所得土地中绿洲面积应满足Wei>=Huo 且二者之差达到最小;
(2)在满足(1)的基础上,Wei的土地面积越大越好。
数据范围:1<=R<=1000000, 1<=N<=10000, 0<=L,T <=R, 1<=W,H<=R
复杂度分析:从所给数据范围看,R在106数量级,既然n取[0,R]的整数,那么若以R为数据规模,对x=i, i:0~R进行步长为1的线性扫描,假设每次迭代中基本操作次数为常数,则渐进复杂度为O(n)。假设计算环境1000ms的时间可完成108规模的基本运算,则本题O(n)的线性扫描思路从渐进复杂度的意义上讲是可行的。
确定了线性扫描的思路,接下来要考虑如何把每轮迭代代价控制在常数以及扫描停止的条件。
1. 如果在每轮迭代中,都检查所有N个绿洲以求出所划分的面积,那么每轮迭代的复杂度为T(N),整体复杂度上升到了T(N*R), 即1010显然不可行。
此方法的低效在于它没有为线性扫描这一“算法”设计合适的“数据结构”来存放绿洲的数据。题目输入的绿洲是一个个分散的个体,而从坐标出发的线性扫描需要快速获得以扫描位置 x=i 为自变量的左侧累加面积,这一“快速”,常数最好,至少不能和N在同一数量级;因此,要进行预处理将原始的绿洲数据转换为以横坐标为中心的统计值,以使每次迭代能用1~2个基本操作得到当前累加面积进而判断下一步的走向。
2. 扫描可以从最左侧的x=0开始,不断向右移动(保证绿洲面积左侧 < 右侧),遇到第一个理想位置(左侧>=右侧,满足了(1))后继续试探,直至抵达最理想的位置(左侧绿洲面积不增的条件下,为满足(2)尽量再往右移动)停止。由于扫描是线性的,可利用一个累加变量,每次只取当前“列”的面积作累加即可。
至此,对绿洲数据的预处理结果要求已经比较明确了,即得到 x=i 代表的一段宽度为1(可以是i ~ i+1)、高度为R的土地中绿洲的总面积,不妨用x[i]表示。
那么这段预处理所花费的时间呢,这回要以N为数据规模来考虑,假设所有绿洲被读入结构体数组中,则对j:0~N-1进行步长为1的线性扫描,假设每次迭代中基本操作次数为常数,N在104数量级,完全可行。但处理每个绿洲真的是常数时间吗,其实应该是T(W),因为要把宽度切分为长度为1的W段,累加到x数组的W个元素上。除非x用的不是朴素的一维数组,否则整体的渐进复杂度应为O(N*W),又是1010。
按以上思路实现的代码,曾WA在long long类型,不应该~:
#include <cstdio>
#include <cstring>
using namespace std;
const int MAX_R = ;
const int MAX_N = ; int K;
int R, N;
struct Rec{
int L, T;
long long W, H; //注意类型!!
}rec[MAX_N];
int x[MAX_R]; int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
scanf("%d",&K);
while(K--){
scanf("%d",&R);
scanf("%d",&N);
memset(x,,sizeof(x));
long long sum = ;
for(int i=; i<N; i++){
scanf("%d%d%d%d",&rec[i].L,&rec[i].T,&rec[i].W,&rec[i].H);
sum += rec[i].W*rec[i].H;
for(int j=rec[i].L; j<rec[i].L+rec[i].W; j++)
x[j] += rec[i].H;
}
long long wei = ;
int i;
for(i=; wei* < sum; i++)
wei += x[i];
while(x[i]== && i<R) i++;
printf("%d\n",i);
}
return ;
}
(若不可避免地1010的话,那么前面被否定的做法是否也可行呢,待续...)
【hihocoder 1249 Xiongnu's Land】线性扫描的更多相关文章
- [ An Ac a Day ^_^ ] HihoCoder 1249 Xiongnu's Land 线性扫描
拿到了icpc北京站的参赛名额 感谢亮哥~ 虽然是地狱之战 但也要全力以赴! 题意: 有一片沙漠 n片绿洲 让你用一条线分成两部分 左≥右 而且分割线要尽量靠右 问线的位置 思路: 网上说可以二分 没 ...
- 二分+贪心 hihocoder 1249 Xiongnu's Land (15北京A)
题目传送门 题意:有多个矩形分布在[0, 0]到[R, R]的的范围内,画一条竖线分割成两块矩形,使得左边包括矩形的面积大于等于右边的面积,在这个前提下使得画的竖线尽量远 分析:二分答案,当面积相等时 ...
- UVALive 7261 Xiongnu's Land (扫描线)
Wei Qing (died 106 BC) was a military general of the Western Han dynasty whose campaigns against the ...
- 【CF56E】Domino Principle(线性扫描,伪DP)
每块多米诺骨牌所在的位置设为x,每块多米诺骨牌高度为h.如果将x位置上的多米诺骨牌向右翻到,它就可以影响[x+1, x+h-1]范围内的所有多米诺骨牌,让他们也翻到,同时这些被翻到的多米诺骨牌还能影响 ...
- 【CF676C】Vasya and String(二分查找,线性扫描尺取法)
题意: 给出一个长度为n的字符串,只有字符'a'和'b'.最多能改变k个字符,即把'a'变成'b'或把'b'变成'a'. 问改变后的最长连续相同字符的字串长度为多少. 首先是二分查找,好想也好写 .. ...
- UVa 1442 (线性扫描) Cave
对于一个水坑,水平面肯定是相等的.(废话,不然为什么叫水ping面) 因为水面不能碰到天花板,所以将水面向两边延伸要么碰到墙壁要么延伸到洞穴外面去. 设h(i)表示向左延伸不会碰到天花板的最高水平面, ...
- (UVALive 7261)Xiongnu's Land 二分
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...
- hiho1249 Xiongnu's Land
题目链接:http://hihocoder.com/problemset/problem/1249 题目大意:有一个大正方形里面有好多不重叠的小矩形,怎么找出一条竖线分割这个正方形,使得两边的矩形面积 ...
- 2015北京区域赛 Xiongnu's Land
Wei Qing (died 106 BC) was a military general of the Western Han dynasty whose campaigns against the ...
随机推荐
- C# 多线程的自动管理(线程池) 基于Task的方式
C# 多线程的自动管理(线程池) 在多线程的程序中,经常会出现两种情况: 1. 应用程序中线程把大部分的时间花费在等待状态,等待某个事件发生,然后给予响应.这一般使用 ThreadPool(线程 ...
- Arcgis api For silverlight 加载QQ地图
原文 http://www.cnblogs.com/thinkaspx/archive/2012/11/07/2759079.html //本篇博客仅在技术上探讨可行性 //如果要使用Q 地图,请 ...
- IIS缺少文件的解决方法
原文 http://cqyccmh.blog.163.com/blog/static/6068134720102211543944/ 今天解决了一个郁闷了很久的问题,之前实在没辙就只能重装系统,因为装 ...
- html模块一些方法
<pre name="code" class="python"> find_by_tag_name: @elements = $h->find ...
- Unix命令行学习
Listing files and directories ls 显示你当前目录的文件 ls -a 显示你千亩目录的文件(包括隐藏文件)ls <name1>/<name2> 显 ...
- LINQ to SQL和Entity Framework对照
LINQ to SQL和Entity Framework都是一种包括LINQ功能的对象关系映射技术.他们之间的本质差别在于EF对数据库架构和我们查询的类型实行了更好的解耦. 使用EF,我们查询的对象不 ...
- 基于纹理边缘抑制的轮廓和边界检测(Contour and Boundary Detection)
基于纹理边缘抑制的轮廓和边界检测(Contour and Boundary Detection) kezunhai@gmail.com http://blog.csdn.net/kezunhai 一幅 ...
- The 2013 South America/Brazil Regional Contest 题解
A: UVALive 6525 cid=61196#problem/A" style="color:blue; text-decoration:none">Atta ...
- PC和ARM平台编译Qt的命令
编译for PC 的Qt过程是: (1)qmake -project (qmake命令,用于创建hello.pro,将所有的文件编译成一个与平台无关的工程文件).(注意:按照前面步骤安装好Qt环境之后 ...
- windows下启动/关闭Sybase数据库服务器
启动.关闭Sybase数据库服务器 一.启动Sybase服务器 在windows下介绍两种方法启动Sybase数据库服务器. 1.通过服务器管理器 依次打开控制面板>管理工具>服务 管理窗 ...