棋子移动问题
棋子移动问题
有2n个棋子(n4)排成一行,
白子用0表示,黑子用1表示,例如n5时初始状态为0 0 0 0 0 1 1 1 1 1 _ _(右边至少有两个空位),
要求通过棋子移动最终成为 0 1 0 1 0 1 0 1 0 1.
移动规则
每次必须同时移动相邻两个棋子
颜色不限,移动方向不限
每次移动必须跳过若干棋子
不能调换这两个棋子的位置
理解:
n = 4时有解,然后看n=5时发现,通过移动中间两枚棋子,再移动左边00或者右边11到中间,可以降为n-1的规模
chess(n)
n=4:move (4,5) (9,10)
move (8,9) (4,5)
move (2,3) (8,9)
move (7,8) (2,3)
move (1,2) (7,8)
n>4:
(n,n+1)->(2n+1, 2n+2);
(2n-2,2n-1)->(n,n+1);
call chess(n-1);
#include <iostream>
#include <algorithm>
#include <cstdlib>
using namespace std;
//棋子移动问题
//有2n个棋子(n4)排成一行,
//白子用0表示,黑子用1表示,例如n5时初始状态为0 0 0 0 0 1 1 1 1 1 _ _(右边至少有两个空位),
//要求通过棋子移动最终成为 0 1 0 1 0 1 0 1 0 1.
//移动规则
// 每次必须同时移动相邻两个棋子
//颜色不限,移动方向不限
// 每次移动必须跳过若干棋子
//不能调换这两个棋子的位置
/*
move (4,5) (9,10)
move (8,9) (4,5)
move (2,3) (8,9)
move (7,8) (2,3)
move (1,2) (7,8)
(n,n+1)->(2n+1, 2n+2);
(2n-2,2n-1)->(n,n+1);
call chess(n-1);
* */
//求n个元素的全排列
//自然数拆分
int a[2000];
void chess(int n)
{
if (4 == n)
{
cout << "move (4,5) (9,10)\n"
"move (8,9) (4,5)\n"
"move (2,3) (8,9)\n"
"move (7,8) (2,3)\n"
"move (1,2) (7,8)";
return ;
}
else
{
cout << "move (" << n << "," << n+1 << " (" << 2*n+1 << "," << 2*n+2 << endl;
cout << "move (" << 2*n-2 << "," << 2*n-1 << " (" << n << "," << n+1 << endl;
chess(n-1);
}
}
int main(void)
{
int n = 5;
for (int i = 1; i <= n; ++i)
{
a[i] = 0;// 黑子
}
for (int j = n+1; j <= 2*n; ++j)
{
a[j] = 1;
}
chess(n);
cout << "end";
}