一道竞赛题 (Winter Camp 2002)

aliceZOOZ 2002-02-18 09:22:19
奶牛浴场
happy.exe

【问题描述】
由于John建造了牛场围栏,激起了奶牛的愤怒,奶牛的产奶量急剧减少。为了讨好奶牛,John决定在牛场中建造一个大型浴场。但是John的奶牛有一个奇怪的习惯,每头奶牛都必须在牛场中的一个固定的位置产奶,而奶牛显然不能在浴场中产奶,于是,John希望所建造的浴场不覆盖这些产奶点。这回,他又要求助于Clevow了。你还能帮助Clevow吗?
John的牛场和规划的浴场都是矩形。浴场要完全位于牛场之内,并且浴场的轮廓要与牛场的轮廓平行或者重合。浴场不能覆盖任何产奶点,但是产奶点可以位于浴场的轮廓上。
Clevow当然希望浴场的面积尽可能大了,所以你的任务就是帮她计算浴场的最大面积。

【输入文件】
输入文件的第一行包含两个整数L和W,分别表示牛场的长和宽。文件的第二行包含一个整数n,表示产奶点的数量。以下n行每行包含两个整数x和y,表示一个产奶点的坐标。所有产奶点都位于牛场内,即:0<x<L,0<y<W。

【输出文件】
输出文件仅一行,包含一个整数S,表示浴场的最大面积。

【输入输出样例】
happy.in
10 10
4
1 1
9 1
1 9
9 9

happy.out
80


【参数约定】
0<n<5000
1<L,W<30000
...全文
102 91 打赏 收藏 转发到动态 举报
写回复
用AI写文章
91 条回复
切换为时间正序
请发表友善的回复…
发表回复
aliceZOOZ 2002-03-10
  • 打赏
  • 举报
回复
既然这样,就先结贴吧
Zig 2002-03-09
  • 打赏
  • 举报
回复
不是没人哩你,我自己都没有搞清楚……………………
cxjddd 2002-03-09
  • 打赏
  • 举报
回复
看来我是超级落后了。
aliceZOOZ 2002-03-08
  • 打赏
  • 举报
回复
没人理我吗?
aliceZOOZ 2002-03-08
  • 打赏
  • 举报
回复
没人理我吗?
aliceZOOZ 2002-03-07
  • 打赏
  • 举报
回复
to Zig(Zig)和所有人: 能简单的谈谈O(nlog^2(n))的算法吗?
NPE 2002-03-07
  • 打赏
  • 举报
回复
I think I was wrong. I didn't read czy888's algorithm carefully. I didn't notice he divided the rectangle at a point n.

But the complexity can't be O(n*log(n)). Even if you can divide the points equally (normally is good), the recursive function for time is
T(n) = 4*T(n/2)
at the best, which cannot be O(n*log(n)). I can prove it's no worse than O(n^2). You have to at least improve the algorithm to get something better than O(n^2).
NPE 2002-03-07
  • 打赏
  • 举报
回复
Of course there is such rectangle. Let me construct one. Assume there are four points at the four corners of the outside rectangle, and there are four points at the centers of four sides of the rectangle. Then the largest empty rectangle (浴场) should be the same as the outside rectangle (牛场围栏). But if you divide the rectangle to form rect_up and rect_down, or rect_left and rect_right, the largest rectangle in each of them is at most the size of rect_up, rect_down, rect_left, or rect_right, which are all smaller than the outside rectangle.

I know there is an O(n*log^2(n)) algorithm discussed on some paper. But I guess that's for professionals. I am glad I have an O(n^2) one. By the way, I still don't understand intfree's program. I know it's correct because it passed the test data. Can someone explain the idea?

Sorry about writing English. It's hard to input Chinese on this machine.
intfree 2002-03-07
  • 打赏
  • 举报
回复
简单解释一下我的程序:

读入
inp >> ww >> hh >> n;
for (i = 0; i < n; i ++)
{
inp >> d[i].x >> d[i].y;
}

加2个点,每个点加2次,(为什么n += 3,下面将解释):
d[n].x = d[n].y = d[n + 1].x = d[n + 1].y = 0;
d[n + 2].x = d[n + 3].x = ww;
d[n + 2].y = d[n + 3].y = hh;
for (i = 0, n += 3; i < n; i ++)
{
dd[i] = i;
}

d[i]按x排序,d[dd[i]]按y排序
qsort(d, n, sizeof(d[0]), sort_x);
qsort(dd, n, sizeof(dd[0]), sort_y);

枚举子矩形
for (i = 1; i < n; i ++)
//i从1开始,n += 3,说明忽略d[0], d[n + 3]这两个点
if (d[i].x != d[i + 1].x)
//按x轴离散化,作为矩形的left
{
int h, last = 0, mh = 0;
long s;
//用一个双向链表把left右边的点串起来
for (j = 1; j < n; j ++)
if (dd[j] > i) //left右边的点
{
mh = ((h = d[dd[j]].y - d[last].y) > mh) ? h : mh;
//mh是这是最大的deltaY
pred[dd[j]] = last;
succ[last] = dd[j];
last = dd[j];
}
succ[last] = n;
max = ((s = (long) mh * (ww - d[i].x)) > max) ? s : max;

关键部分
for (j = n - 1; j > i; j --)
//枚举矩形的right,注意j是递减的
{
//从双向链表中删除j这个点
pred[succ[j]] = pred[j];
succ[pred[j]] = succ[j];
//更新mh
if ((h = d[succ[j]].y - d[pred[j]].y) > mh)
{
//更新max
max = ((s = (long) (mh = h) * (d[j].x - d[i].x)) > max) ? s : max;
}
}
}

输出
out << max << endl;
Zig 2002-03-06
  • 打赏
  • 举报
回复
这个算法太变态了,其中的LECR的算法我看不懂,谁能解释一下?
Zig 2002-03-06
  • 打赏
  • 举报
回复
to NPE,
可能存在那个长方形吗?!

n^2的算法已经有了,现在有没有更好的? nlog^2n我基本理解了,但写程序..
Zig 2002-03-06
  • 打赏
  • 举报
回复
不是啊,是10060:(
NPE 2002-03-06
  • 打赏
  • 举报
回复
我写了一个O(n^2)的算法(没编程序),英文的(中文不好输入),在
<http://www.cs.uoregon.edu/~xma/Problem.doc>
NPE 2002-03-06
  • 打赏
  • 举报
回复
别光算复杂度,还有正确性呢。czy888()的分治法有问题,浴场1、浴场2、浴场3、浴场4中最大的那个不见得是最大的,有可能有一个既横跨rect_left和rect_right又纵跨rect_up和rect_down的长方形比它们都大。
czy888 2002-03-05
  • 打赏
  • 举报
回复
大哥,O(nlogn)就是O(nlog^2n)啊!
其实O(nlog^xn)都是相同的!
因为 log^xn = log^2n/log^2x。 log^2x是常数,在O()表示法中无意义。
一不小心,用了大家不熟的表示法,请原谅。
算法肯定是对的。
aliceZOOZ 2002-03-05
  • 打赏
  • 举报
回复
一篇13页(290-278+1=13)的论文,就讲这个东西,看来O(nlog^2n)的算法还是很复杂的,当然不排除老外很啰嗦的说。至于czy888()说的那个O(nlogn)的算法,我想如果不是算法错了,就是复杂度算错了。
aliceZOOZ 2002-03-05
  • 打赏
  • 举报
回复
A. Aggarwal and S. Suri, Fast Algorithms for Computing the Largest Empty Rectangle, Proceedings of the 3rd Symposium on Computational Geometry, pages 278-290, 1987
一篇1995年的文章说,上面这篇文章(Fast Algorithms for Computing the Largest Empty Rectangle)中给出了一个O(nlog^2n)的算法,叫做"Fast Matrix"算法,是当时(或许也是现在)最好的算法,但没有给出具体的描述。而我也没有找到Fast Algorithms for Computing the Largest Empty Rectangle的原文。不知斑竹有没有这方面的资料。
Zig 2002-03-05
  • 打赏
  • 举报
回复
不对,复杂度好像比n^2还大。
谁有实际的运行时间比较一下?
Zig 2002-03-05
  • 打赏
  • 举报
回复
在网上可以找到的,搜索Largest Empty Rectangle问题。
aliceZOOZ 2002-03-05
  • 打赏
  • 举报
回复
to Zig(Zig): 冒昧的问一句,既然你不知道,又如何得知有O(nlog^2(n))的算法呢?难道你也是听说的?能告诉我,你是听哪位高手说的吗?
加载更多回复(71)

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧