gpt4 book ai didi

algorithm - 拼图 : Find largest rectangle (maximal rectangle problem)

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:13:50 26 4
gpt4 key购买 nike

找到适合空白空间的面积最大的矩形的最有效算法是什么?

假设屏幕看起来像这样('#' 代表填充区域):

....................
..............######
##..................
.................###
.................###
#####...............
#####...............
#####...............

一个可能的解决方案是:

....................
..............######
##...++++++++++++...
.....++++++++++++###
.....++++++++++++###
#####++++++++++++...
#####++++++++++++...
#####++++++++++++...

通常我会很乐意找出解决方案。虽然这次我想避免浪费时间自己摸索,因为这对我正在从事的项目有实际用途。是否有众所周知的解决方案?

Shog9 写道:

Is your input an array (as implied by the other responses), or a list of occlusions in the form of arbitrarily sized, positioned rectangles (as might be the case in a windowing system when dealing with window positions)?

是的,我有一个结构可以跟踪放置在屏幕上的一组窗口。我还有一个网格,它跟踪每个边缘之间的所有区域,无论它们是空的还是填充的,以及它们的左边缘或上边缘的像素位置。我认为有一些修改形式可以利用此属性。你知道吗?

最佳答案

我是 Dobb 博士那篇文章的作者,偶尔​​会被问到有关实现的问题。这是一个简单的 C 语言:

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct {
int one;
int two;
} Pair;

Pair best_ll = { 0, 0 };
Pair best_ur = { -1, -1 };
int best_area = 0;

int *c; /* Cache */
Pair *s; /* Stack */
int top = 0; /* Top of stack */

void push(int a, int b) {
s[top].one = a;
s[top].two = b;
++top;
}

void pop(int *a, int *b) {
--top;
*a = s[top].one;
*b = s[top].two;
}


int M, N; /* Dimension of input; M is length of a row. */

void update_cache() {
int m;
char b;
for (m = 0; m!=M; ++m) {
scanf(" %c", &b);
fprintf(stderr, " %c", b);
if (b=='0') {
c[m] = 0;
} else { ++c[m]; }
}
fprintf(stderr, "\n");
}


int main() {
int m, n;
scanf("%d %d", &M, &N);
fprintf(stderr, "Reading %dx%d array (1 row == %d elements)\n", M, N, M);
c = (int*)malloc((M+1)*sizeof(int));
s = (Pair*)malloc((M+1)*sizeof(Pair));
for (m = 0; m!=M+1; ++m) { c[m] = s[m].one = s[m].two = 0; }
/* Main algorithm: */
for (n = 0; n!=N; ++n) {
int open_width = 0;
update_cache();
for (m = 0; m!=M+1; ++m) {
if (c[m]>open_width) { /* Open new rectangle? */
push(m, open_width);
open_width = c[m];
} else /* "else" optional here */
if (c[m]<open_width) { /* Close rectangle(s)? */
int m0, w0, area;
do {
pop(&m0, &w0);
area = open_width*(m-m0);
if (area>best_area) {
best_area = area;
best_ll.one = m0; best_ll.two = n;
best_ur.one = m-1; best_ur.two = n-open_width+1;
}
open_width = w0;
} while (c[m]<open_width);
open_width = c[m];
if (open_width!=0) {
push(m0, w0);
}
}
}
}
fprintf(stderr, "The maximal rectangle has area %d.\n", best_area);
fprintf(stderr, "Location: [col=%d, row=%d] to [col=%d, row=%d]\n",
best_ll.one+1, best_ll.two+1, best_ur.one+1, best_ur.two+1);
return 0;
}

它从控制台获取输入。你可以例如将此文件通过管道传递给它:

16 12
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 1 1 0 0 1 0 0 0 1 1 0 1 0
0 0 0 1 1 0 1 1 1 0 1 1 1 0 1 0
0 0 0 0 1 1 * * * * * * 0 0 1 0
0 0 0 0 0 0 * * * * * * 0 0 1 0
0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 0
0 0 1 0 0 0 0 1 0 0 1 1 1 0 1 0
0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0

打印输入后,输出:

The maximal rectangle has area 12.
Location: [col=7, row=6] to [col=12, row=5]

上面的实现当然没什么特别的,但它与 Dr. Dobb 的文章中的解释非常接近,应该很容易翻译成任何需要的东西。

关于algorithm - 拼图 : Find largest rectangle (maximal rectangle problem),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7245/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com