帮助解决几何问题 - 没有任何想法

时间:2010-02-12 21:14:45

标签: c++ geometry

我正准备参加编程比赛,我想知道如何解决这个问题。我想这是几何问题,似乎我无法得到任何解决它的想法。

这是:

有一个院子里有狼和羊。在院子里也有不允许通过的街区。狼用'w'表示,羊用's'表示,而块用'#'表示,每个人都可以移动的空间是'。' 。所以可能的输入看起来像:

8 8
.######.
#..s...#
#.####.#
#.#w.#.#
#.#.s#s#
#s.##..#
#.w..w.#
.######.

院子上方的2个数字是行x列。

正如你所看到的那样,在院子里可以形成不同类型的扇区。这是两个部门:

####
#.w#
####
#s.#

在第一个中有一只狼,在第二只中有一只羊。因为它们被放置在两个不同的部分(即狼不能到达绵羊),他不能吃它。如果他们在同一个区域,狼就会吃掉羊。

我的问题是:鉴于上述输入,我应该如何计算有多少只羊存活?我怎样才能代表c ++中的“码”?该算法应该如何?是否有任何材料可以理解类似的问题和问题?

感谢任何帮助。先感谢您。

7 个答案:

答案 0 :(得分:4)

此问题基本上是找到给定图表的connected sub-graphs (aka components)的问题。

您可以通过将每个“非块”坐标表示为图形节点来解决问题,从而链接图形中的2个相邻坐标。然后使用BFS(或任何其他适合该主题的算法)找到连接的子图 - 我确定任何网页或图表算法上的Wiki都会有一个各种算法的列表。

获得子图后,只需找到哪些子图有零狼(通过查找每个狼坐标所在的子图),并在这些子图中计算羊。

希望这足以让你开始。

答案 1 :(得分:1)

您在这里寻找的是找到图表的连通成分,然后您只需要计算每一个中的狼和羊的数量。

using namespace std;

int w, h;
cin >> w >> h;
vector<string> grid(h);
for (int i = 0; i < h; ++i)
  cin >> grid[i];

vector< vector<bool> > seen(h, vector<bool>(w, false));
int survived = 0;
const int mx[] = {-1, 0, 1, 0}, my[] = {0, -1, 0, 1};

for (int i = 0; i < h; ++i)
  for (int j = 0; j < w; ++j)
    if (!seen[i][j] && grid[i][j] != '#')
    {
      int sheep = 0, wolves = 0;
      typedef pair<int, int> point;
      stack<point> s;
      s.push(point(i, j));

      while (!s.empty())
      {
        point p = s.top();
        int x = p.first, y = p.second;
        if (grid[x][y] == 'w') wolves++;
        if (grid[x][y] == 's') sheep++;
        for (int k = 0; k < 4; ++k)
        {
          int x2 = x + mx[k], y2 = y + my[k];
          if (x2<0 || x2>=h || y2<0 || y2>=w) continue;
          if (grid[x2][y2] == '#' || seen[x2][y2]) continue;
          s.push(point(x2, y2));
        }
      }
      survived += max(0, sheep - wolves);
    }

cout << "Surviving sheep = " << survived << endl;

O(行x列)的运行时间和内存使用情况最佳。

请注意,代码未经测试,但我相信这应该可行。

答案 2 :(得分:1)

一个简单的方法是从每只狼开始flood fill。你可以假设每只狼都会移动(填充)他周围的点。从所有点开始填充之后,任何剩余的绵羊都将存活下来。

在你的例子中:

####
#.w#
####
#s.#

将填写:

####
#fw#
####
#s.#

(我用f填充空格),算法将停止,因此s将继续存在。

答案 3 :(得分:0)

或许可以尝试将院子视为一组扇区。在创建扇区时,如果有狼,则移除所有绵羊。现在唯一的挑战是代表一个似乎更容易管理的行业。

答案 4 :(得分:0)

考虑使用flood filling算法的逻辑。

答案 5 :(得分:0)

对我来说看起来不像几何问题。我会用Flood fill算法

来解决它

使用唯一编号填写每个区域。然后,对于您填充区域的每个数字,找出有多少只绵羊以及与该数字相邻的狼群数量。唯一幸存的绵羊是那些与没有狼相邻的数字k相邻的绵羊。

您可以将C ++中的矩阵表示为字符矩阵:char A [maxrows] [maxcols]。但是,要使用泛洪填充,我会使用一个整数矩阵,因为你可能有更多的区域而不是一个字符的最大值。

答案 6 :(得分:0)

这是一次有时间限制的比赛吗?例如,你的分数是在给定时间内解决的程序数量的函数吗?

对于这些,我建议基于两件事的简单方法:

  • 将数据表示为2D数组

  • 通过搜索连接来确定绵羊和狼共享扇区的时间,使用类似每只狼的泛洪填充算法。我建议你从狼群开始,当你到达它们时“杀掉”绵羊。在为每只狼做完这个之后,数据结构中任何剩余的绵羊都会存活下来。

时间限制比赛的关键是提出一个快速编程的简单解决方案。现代计算机非常快。除非你需要能够处理大量的数据集,否则不要考虑几何算法,只要想想我怎么能在问题上抛出计算来轻松解决它。

虽然我想到了其他几个人建议填充洪水,所以这有点多余。