- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
给定一个二维 n*n
数组,每个元素是 +
或 x
,我们如何找到最大圆直径仅由 +
个字符组成。
例如:
xxxxx
x++++
x+++x
x+++x
xxxxx
最大直径为 2,圆原点为圆心。
在所有情况下,圆可能不会在二维数组中居中。
有没有简单的算法可以解决这个问题?我不是在寻找代码只是一种算法。谢谢。
xxxxx
xx+xx
x+++x
xx+xx
xxxxx
将是一个直径为 2 的圆来回答有关边的问题。
最佳答案
解决此问题的一种方法是将空闲单元格 (+
) 想象成海洋,将其他单元格 (x
) 想象成陆地。该算法在海岸线开始向各个方向流动的水波(直到它碰到另一个波浪或陆地)。被波浪覆盖的最后一片海是半径最大的圆心。
这导致了这个更正式的算法:
count
为空闲单元格的数量(+
的数量)。 count
为零,无结果退出。coast
,其中包含已占用单元格的单元格坐标(那些带有 x
的单元格)
海岸
添加位于网格外的虚拟单元格,因为它们也代表“陆地”。半径
设为1获取具有此 radius
的圆的相对坐标(好像以单元格 [0, 0] 为中心)。所以对于半径 1 这将是:
[ [-1, 0], [0, -1], [1, 0], [0, 1] ]
对于每个 centre
= coast
中引用的单元格:
centre
和 radius
获取圆上的空闲单元格,对于每个单元格:
计数
count
为零,那么我们有一个解决方案:这个单元格是要绘制的圆的中心,它的半径应该是radius-1
。退出。coast
中删除 centre
(以避免将来进行不必要的检查)7. 增加 radius
并从第 5 步开始重复。
当算法以结果(中心和半径)退出时,直接将给定网格与实际圆盘叠加。
这是 JavaScript 中的一个实现(没有使用任何较新的语法,因此应该很容易阅读),您可以在此处运行:
"use strict";
function circleCoordinates(radius) {
var cells = [];
var r2 = (radius+0.41)*(radius+0.41); // constant determines margin
var i = 0;
var j = radius;
while (i <= j) {
cells.push([ i, j]);
cells.push([ i, -j]);
if (i < j) {
cells.push([ j, i]);
cells.push([-j, i]);
}
if (i) {
cells.push([-i, j]);
cells.push([-i, -j]);
if (i < j) {
cells.push([j, -i]);
cells.push([-j, -i]);
}
}
i++;
if (i*i + j*j > r2) {
j--;
// Decrementing i here is not standard, but needed to make
// sure we cover the surface added compared to a disk with
// a radius of one unit one less.
i--;
}
}
return cells;
}
function solve(a) {
var i, j, k, l, m, n, count, coast, circle, reduced, radius, b;
function get(b, i, j) {
if (i < 0 || j < 0 || i >= b.length || j >= b[i].length)
return 1;
return b[i][j];
}
// Copy input, count free cells, and collect the others in "coast"
count = 0;
coast = [];
b = [];
for (i = 0; i < a.length; i++) {
b[i] = [];
for (j = 0; j < a[i].length; j++) {
b[i].push(a[i][j]); // copy array element
count += !b[i][j]; // count free cells
if (b[i][j]) coast.push([i,j]); // push occupied cells
}
}
if (!count) return; // no solution
// To bound the area, add virtual border cells in 'coast':
for (i = 0; i < b.length; i++) {
coast.push([i, -1], [i, b[i].length]);
}
for (j = 0; j < b[0].length; j++) {
coast.push([-1, j], [b.length, j]);
}
// Keep reducing free space by drawing circles from the coast
// until one free cell is left over.
radius = 0;
while (count) {
radius++;
circle = circleCoordinates(radius);
for (k = coast.length - 1; (k >= 0) && count; k--) {
reduced = false;
for (l = 0; (l < circle.length) && count; l++) {
m = coast[k][0] + circle[l][0];
n = coast[k][1] + circle[l][1];
if (!get(b, m, n)) {
b[m][n] = radius+1;
count--;
reduced = true;
}
}
// Save some time by removing the cell in the coast
// list that had no reducing effect anymore:
if (!reduced) coast.splice(k, 1);
}
}
// Greatest circle has a radius that is one smaller:
radius--;
// Restore array to original
for (i = 0; i < b.length; i++) {
for (j = 0; j < b[i].length; j++) {
b[i][j] = a[i][j];
}
}
// Draw a disc centered at i, j
circle = circleCoordinates(radius);
for (l = 0; l < circle.length; l++) {
for (k = m + circle[l][0]; k <= m - circle[l][0]; k++) {
b[k][n+circle[l][1]] = 2;
}
}
// Return the array with the marked disc
return b;
}
// String handling
function cleanText(txt) {
return txt.trim().replace(/[ \r\t]/g, '').replace(/[^x\n]/g, '+');
}
function textToArray(txt) {
var lines, a, i, j;
// Clean text and split into lines
lines = cleanText(txt).split('\n');
// convert to 2D array of 0 or 1:
a = [];
for (i = 0; i < lines.length; i++) {
a[i] = [];
for (j = 0; j < lines[i].length; j++) {
a[i][j] = +(lines[i][j] !== '+'); // '+' => 0, 'x' => 1
}
}
return a;
}
function arrayToText(a) {
// Convert 2D array back to text. 2-values will be translated to '#'
var lines, i, j;
lines = [];
for (i = 0; i < a.length; i++) {
lines[i] = [];
for (j = 0; j < a[i].length; j++) {
lines[i][j] = '+x#'[a[i][j]]; // mark disc with '#'
}
lines[i] = lines[i].join('');
}
return lines.join('\n');
}
// I/O handling for snippet:
var inp = document.querySelector('textarea');
var solveBtn = document.querySelector('#solve');
var clearBtn = document.querySelector('#clear');
solveBtn.onclick = function() {
// Convert input to 2D array of 0 and 1 values:
var a = textToArray(inp.value);
// Draw greatest disk by replacing 0-values with 2-values:
a = solve(a);
// Convert 2D array back to text. 2-values will be translated to '#'
inp.value = arrayToText(a);
};
clearBtn.onclick = function() {
inp.value = cleanText(inp.value);
};
<button id="solve">Show Greatest Disc</button>
<button id="clear">Remove Disc</button><br>
<textarea rows=10>
xxxxxxxxxxxxxxxxxx
xxxxx++++++x++++++
+++x+++++++x+++++x
++++x+++++++++++x+
++++x+++++x++++x++
+++x+++++++x+++x+x
x+++++xx+++++x++++
xx+++++x+++++x+++x
++++++xxxx++xxxx++
xxx++xxxxxxxxxxxx+
++xxxxxxxxx+xxxxxx</textarea>
<pre></pre>
关于algorithm - 如何找到二维数组中的最大圆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39472211/
我想做的是让 JTextPane 在 JPanel 中占用尽可能多的空间。对于我使用的 UpdateInfoPanel: public class UpdateInfoPanel extends JP
我在 JPanel 中有一个 JTextArea,我想将其与 JScrollPane 一起使用。我正在使用 GridBagLayout。当我运行它时,框架似乎为 JScrollPane 腾出了空间,但
我想在 xcode 中实现以下功能。 我有一个 View Controller 。在这个 UIViewController 中,我有一个 UITabBar。它们下面是一个 UIView。将 UITab
有谁知道Firebird 2.5有没有类似于SQL中“STUFF”函数的功能? 我有一个包含父用户记录的表,另一个表包含与父相关的子用户记录。我希望能够提取用户拥有的“ROLES”的逗号分隔字符串,而
我想使用 JSON 作为 mirth channel 的输入和输出,例如详细信息保存在数据库中或创建 HL7 消息。 简而言之,输入为 JSON 解析它并输出为任何格式。 最佳答案 var objec
通常我会使用 R 并执行 merge.by,但这个文件似乎太大了,部门中的任何一台计算机都无法处理它! (任何从事遗传学工作的人的附加信息)本质上,插补似乎删除了 snp ID 的 rs 数字,我只剩
我有一个以前可能被问过的问题,但我很难找到正确的描述。我希望有人能帮助我。 在下面的代码中,我设置了varprice,我想添加javascript变量accu_id以通过rails在我的数据库中查找记
我有一个简单的 SVG 文件,在 Firefox 中可以正常查看 - 它的一些包装文本使用 foreignObject 包含一些 HTML - 文本包装在 div 中:
所以我正在为学校编写一个 Ruby 程序,如果某个值是 1 或 3,则将 bool 值更改为 true,如果是 0 或 2,则更改为 false。由于我有 Java 背景,所以我认为这段代码应该有效:
我做了什么: 我在这些账户之间创建了 VPC 对等连接 互联网网关也连接到每个 VPC 还配置了路由表(以允许来自双方的流量) 情况1: 当这两个 VPC 在同一个账户中时,我成功测试了从另一个 La
我有一个名为 contacts 的表: user_id contact_id 10294 10295 10294 10293 10293 10294 102
我正在使用 Magento 中的新模板。为避免重复代码,我想为每个产品预览使用相同的子模板。 特别是我做了这样一个展示: $products = Mage::getModel('catalog/pro
“for”是否总是检查协议(protocol)中定义的每个函数中第一个参数的类型? 编辑(改写): 当协议(protocol)方法只有一个参数时,根据该单个参数的类型(直接或任意)找到实现。当协议(p
我想从我的 PHP 代码中调用 JavaScript 函数。我通过使用以下方法实现了这一点: echo ' drawChart($id); '; 这工作正常,但我想从我的 PHP 代码中获取数据,我使
这个问题已经有答案了: Event binding on dynamically created elements? (23 个回答) 已关闭 5 年前。 我有一个动态表单,我想在其中附加一些其他 h
我正在尝试找到一种解决方案,以在 componentDidMount 中的映射项上使用 setState。 我正在使用 GraphQL连同 Gatsby返回许多 data 项目,但要求在特定的 pat
我在 ScrollView 中有一个 View 。只要用户按住该 View ,我想每 80 毫秒调用一次方法。这是我已经实现的: final Runnable vibrate = new Runnab
我用 jni 开发了一个 android 应用程序。我在 GetStringUTFChars 的 dvmDecodeIndirectRef 中得到了一个 dvmabort。我只中止了一次。 为什么会这
当我到达我的 Activity 时,我调用 FragmentPagerAdapter 来处理我的不同选项卡。在我的一个选项卡中,我想显示一个 RecyclerView,但他从未出现过,有了断点,我看到
当我按下 Activity 中的按钮时,会弹出一个 DialogFragment。在对话框 fragment 中,有一个看起来像普通 ListView 的 RecyclerView。 我想要的行为是当
我是一名优秀的程序员,十分优秀!