三十六军官问题的应用

如题所述

第1个回答  2016-06-01

这种方阵在近代组合数学中称为正交拉丁方,它在工农业生产和科学实验方面有广泛的应用。现已经证明,除了2阶和6阶以外,其它各阶3,4,5,7,8,……各阶正交拉丁方都是作得出来的。
除了上面的定义外需要注意的是每个组合不能重复,如2阶方正会出现类似如下情况:
(1,1) (2,2)
(2,2) (1,1)
由于出现类似(1,1)的重复,问题中36个军官不可能同时站在不同位置,故不满足需求,所以2阶方正不存在。根据计算机编程能很容易求得3,4,5阶的方正,由于组合众多,现举例如下:
3阶:
(1,1) (2,2) (3,3)
(2,3) (3,1) (1,2)
(3,2) (1,3) (2,1)
4阶:
(2,1) (4,4) (3,2) (1,3)
(4,2) (2,3) (1,1) (3,4)
(3,3) (1,2) (2,4) (4,1)
(1,4) (3,1) (4,3) (2,2)
5阶:
(1,1) (2,2) (3,5) (4,3) (5,4)
(4,5) (1,3) (5,2) (3,4) (2,1)
(2,4) (5,5) (4,1) (1,2) (3,3)
(5,3) (3,1) (1,4) (2,5) (4,2)
(3,2) (4,4) (2,3) (5,1) (1,5)
c++ 代码如下: #include <iostream>#define ARMY_SIZE 5typedef struct snode { int x; int y;}node;void set_value(int x, int y);bool can_set(int x, int y, int i, int j);void set_next(int x, int y); node nodes[ARMY_SIZE][ARMY_SIZE];int main(void){ memset(nodes, 0, sizeof(nodes)); set_value(0, 0); std::cout << end... << std::endl;  std::cin.get();  return 0; }void set_value(int x, int y){ for (int i = 1; i < ARMY_SIZE + 1; ++i) { for (int j = 1; j < ARMY_SIZE + 1; ++j) { if (can_set(x, y, i, j)) { nodes[x][y].x = i; nodes[x][y].y = j; set_next(x, y); nodes[x][y].x = 0; nodes[x][y].y = 0; } } }}bool can_set(int x, int y, int i, int j){ for (int _x = 0; _x < x; ++_x) { if (nodes[_x][y].x == i || nodes[_x][y].y == j) return false; } for (int _z = 0; _z < x; ++_z) { for (int _i = 0; _i < ARMY_SIZE; ++_i) { if (nodes[_z][_i].x == i && nodes[_z][_i].y == j) { return false; } } } for (int _y = 0; _y < y; ++_y) { if (nodes[x][_y].x == i || nodes[x][_y].y == j) return false; } return true; }void set_next(int x, int y){ if (y + 1 == ARMY_SIZE) { if (x + 1 == ARMY_SIZE) { for (int i = 0; i < ARMY_SIZE; ++i) { for (int j = 0; j < ARMY_SIZE; ++j) { std::cout << ( << nodes[i][j].x << , << nodes[i][j].y << ) ; } std::cout << std::endl; } std::cout << ************************************* << std::endl; } else { set_value(x + 1, 0); } } else { set_value(x, y + 1); }}

相似回答
大家正在搜