【问题标题】:Project: Body Scanner, ACM 1993 [closed]项目:身体扫描仪,ACM 1993 [关闭]
【发布时间】:2012-02-11 15:42:29
【问题描述】:

我有一个非常困难的项目,我必须为我的大学做。这是一个身体扫描仪,其概念基于1993's ACM Final's problem H,Scanner。

请看图理解问题。

所以,就我们而言。我需要您的帮助来制作一种算法,该算法可以获取数据输入的数字并根据这些数字生成一个表格(在我们的例子中为 10x15)。前 10 个数字表示每行 (1) 中非白色单元格的数量。接下来的 24 是从左到右对角线 (2) 中非白色单元格的数量。接下来的 15 个是每列中非白色单元格的数量 (3),最后 24 个是从右到左对角线中的非白色单元格的数量 (4)。我一直在想一种算法,可以结合所有这些数据并创建数组,但没有结果。

【问题讨论】:

  • 让我们看看你目前得到了什么
  • 我已经设法编写了一些代码来填充'1' 的完整行和列,或者'0' 的空行或列。我现在正在研究完整/空对角线。这就像 pic-a-pix 谜题 (Link here) 的解决方案,但我也必须将对角线与我的算法结合起来,这使得它变得复杂。
  • 您知道在您链接的页面上有解决方案,对吧?
  • MK,我当然注意到了示例解决方案,但我不能只是将解决方案复制并粘贴到我的工作中。我不能使用我不理解的东西。那个解决方案很好用,但是我看不懂程序员的逻辑。
  • @Someone 我认为自己弄清楚那里的代码是一个很好的练习。

标签: c arrays algorithm tomography-reconstruction


【解决方案1】:

嗯,行和列很简单。它们只是 x 或 y 坐标。

游戏正在检测对角线。

如果你想一想,这并不难。

考虑:

a
ba
cba
dcba
edcba

稍加研究,您就可以看到单元格和对角线之间的关系。

但是桌子的另一半呢?

考虑一下:

a
ba
cba
dcba
-----
edcba
fedcb
gfedc
hgfed
ihgfe
-----
 ihgf
  ihg
   ih
    i

线条是表格的边界,但您可以看到对角线只是从表格“外部”突出。因此,一旦您可以解决基本情况(对于桌子上的那些),可以说“让您的桌子更大”。例如,要找出右上角“a”的对角线,您可能会得到“对角线数”,哦,-4 或 -5(类似的东西)。只需将其与其余部分一起移回(即添加 4 或 5),这会将“a”对角线移动到 0(或您想要的任何位置)。

但归根结底,对角线和其他行列式只是基于坐标的函数。算出这些方程式,你就完成了。

【讨论】:

  • 谢谢,我现在正在研究我的方程式。我找到了从左到右对角线的方程,现在我正在研究从右到左对角线的方程。
【解决方案2】:

对此的一般回答是,它类似于 CAT 扫描,并且有一篇非常好的介绍性文章 Saving lives: the mathematics of tomography 简要概述了它是如何完成的 (invert the Radon transform using a Fourier transform)。

另一方面,我很难相信编程比赛会期望你这样做,所以我怀疑对于简单的情况,可以将其视为约束满足问题,因此您可以尝试搜索可能的空间解决方案并在解决方案与约束不匹配的地方切断搜索。根据您构建搜索的方式以及检查约束的效率,这可能足以解决小问题。

【讨论】:

    【解决方案3】:

    我太喜欢逻辑练习了,所以不能让这个通过我,所以我花了一段时间在 javascript 中制定一个解决方案。首先,代码创建了一个表格来显示结果并用作数据结构,然后有四个函数用于检查水平线、垂直线和两条对角线。这四个函数中的每一个都具有相同的形式:在每一行上,找到未设置值的空闲单元格的数量,以及包含主体的完整单元格的数量。然后,如果有足够的空闲单元格用于包含身体的剩余单元格,则填充这些单元格。最后,如果没有包含正文的剩余单元格,则将剩余的空闲单元格标记为空。

    之后,剩下的就是冲洗并重复。每次运行四个函数中的一个时,都会有更多的单元格被标记为已满或为空,从而使下一个函数能够在更多约束条件下执行相同的操作。所有四个函数的三遍解决了您的示例问题,尽管更大和更复杂的形状肯定需要更多,如果它们可以解决的话。我可以很容易地想象这种方法无法解决的形状。

    function create(rows, cols) {
      var table = document.createElement('table');
      for (var i = 0; i < rows; i++) {
        var row = table.insertRow(-1);
        for (var k = 0; k < cols; k++) {
          var cell = row.insertCell(-1);
          cell.value = null;
          cell.innerHTML = '&nbsp;';
          cell.style.width = '15px';
          cell.style.backgroundColor = '#cccccc';
        }
      }
      table.maxrow = rows - 1;
      table.maxcol = cols - 1;
      document.body.appendChild(table);
      return table;
    }
    function checkRows(table, rows) {
      for (var i = 0; i < rows.length; i++) {
        var free = 0;
        var full = 0;
        for (var k = 0; k <= table.maxcol; k++) {
          if (table.rows[i].cells[k].value == null) {
            free++;
          } else if (table.rows[i].cells[k].value == 1) {
            full++;
          }
        }
        if (free == 0) {
          continue;
        } else if (rows[i] - full == free) {
          for (var k = 0; k <= table.maxcol; k++) {
            if (table.rows[i].cells[k].value == null) {
              table.rows[i].cells[k].style.backgroundColor = '#ffcccc';
              table.rows[i].cells[k].value = 1;
            }
          }
        } else if (rows[i] - full == 0) {
          for (var k = 0; k <= table.maxcol; k++) {
            if (table.rows[i].cells[k].value == null) {
              table.rows[i].cells[k].style.backgroundColor = '#ccffcc';
              table.rows[i].cells[k].value = 0;
            }
          }
        }
      }
    }
    function checkCols(table, cols) {
      for (var i = 0; i < cols.length; i++) {
        var free = 0;
        var full = 0;
        for (var k = 0; k <= table.maxrow; k++) {
          if (table.rows[k].cells[i].value == null) {
            free++;
          } else if (table.rows[k].cells[i].value == 1) {
            full++;
          }
        }
        if (free == 0) {
          continue;
        } else if (cols[i] - full == free) {
          for (var k = 0; k <= table.maxrow; k++) {
            if (table.rows[k].cells[i].value == null) {
              table.rows[k].cells[i].style.backgroundColor = '#ffcccc';
              table.rows[k].cells[i].value = 1;
            }
          }
        } else if (cols[i] - full == 0) {
          for (var k = 0; k <= table.maxrow; k++) {
            if (table.rows[k].cells[i].value == null) {
              table.rows[k].cells[i].style.backgroundColor = '#ccffcc';
              table.rows[k].cells[i].value = 0;
            }
          }
        }
      }
    }
    function checkDiagonals1(table, diagonals) {
      for (var i = 0; i < diagonals.length; i++) {
        var row = i;
        var col = 0;
        if (i > table.maxrow) {
          row = table.maxrow;
          col = i - row;
        }
        var free = 0;
        var full = 0;
        for (var k = 0; k <= row && col + k <= table.maxcol; k++) {
          if (table.rows[row - k].cells[col + k].value == null) {
            free++;
          } else if (table.rows[row - k].cells[col + k].value == 1) {
            full++;
          }
        }
        if (free == 0) {
          continue;
        } else if (diagonals[i] - full == free) {
          for (var k = 0; k <= row && col + k <= table.maxcol; k++) {
            if (table.rows[row - k].cells[col + k].value == null) {
              table.rows[row - k].cells[col + k].style.backgroundColor = '#ffcccc';
              table.rows[row - k].cells[col + k].value = 1;
            }
          }
        } else if (diagonals[i] - full == 0) {
          for (var k = 0; k <= row && col + k <= table.maxcol; k++) {
            if (table.rows[row - k].cells[col + k].value == null) {
              table.rows[row - k].cells[col + k].style.backgroundColor = '#ccffcc';
              table.rows[row - k].cells[col + k].value = 0;
            }
          }
        }
      }
    }
    function checkDiagonals2(table, diagonals) {
      for (var i = 0; i < diagonals.length; i++) {
        var row = table.maxrow;
        var col = i;
        if (i > table.maxcol) {
          row = table.maxrow - i + table.maxcol;
          col = table.maxcol;
        }
        var free = 0;
        var full = 0;
        for (var k = 0; k <= row && k <= col; k++) {
          if (table.rows[row - k].cells[col - k].value == null) {
            free++;
          } else if (table.rows[row - k].cells[col - k].value == 1) {
            full++;
          }
        }
        if (free == 0) {
          continue;
        } else if (diagonals[i] - full == free) {
          for (var k = 0; k <= row && k <= col; k++) {
            if (table.rows[row - k].cells[col - k].value == null) {
              table.rows[row - k].cells[col - k].style.backgroundColor = '#ffcccc';
              table.rows[row - k].cells[col - k].value = 1;
            }
          }
        } else if (diagonals[i] - full == 0) {
          for (var k = 0; k <= row && k <= col; k++) {
            if (table.rows[row - k].cells[col - k].value == null) {
              table.rows[row - k].cells[col - k].style.backgroundColor = '#ccffcc';
              table.rows[row - k].cells[col - k].value = 0;
            }
          }
        }
      }
    }
    
    var rows = new Array(10, 10, 6, 4, 6, 8, 13, 15, 11, 6);
    var cols = new Array(2, 4, 5, 5, 7, 6, 7, 10, 10, 10, 7, 3, 3, 5, 5);
    var diagonals1 = new Array(0, 1, 2, 2, 2, 2, 4, 5, 5, 6, 7, 6, 5, 6, 6, 5, 5, 6, 6, 3, 2, 2, 1, 0);
    var diagonals2 = new Array(0, 0, 1, 3, 4, 4, 4, 4, 3, 4, 5, 7, 8, 8, 9, 9, 6, 4, 4, 2, 0, 0, 0, 0);
    var table = create(rows.length, cols.length);
    
    checkRows(table, rows);
    checkCols(table, cols);
    checkDiagonals1(table, diagonals1);
    checkDiagonals2(table, diagonals2);
    

    【讨论】:

    • 我明天要去看看这个解决方案。我认为它会起作用,非常感谢。
    • 只有一个问题,javascript中的“继续”表达是什么?我还不懂java,只会C。
    • 请参阅此处了解continue 所做的简要说明:en.wikipedia.org/wiki/…。它是在任何语言中都可以找到的基本结构,但并不总是具有相同的名称。在这里,如果没有找到空闲单元格,我将使用它来停止执行循环迭代,因为在这种情况下无事可做。
    猜你喜欢
    • 1970-01-01
    • 2015-03-19
    • 2014-06-29
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 2018-08-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多