算法--递归(2)

棋子移动问题

棋子移动问题
有2n个棋子(n4)排成一行,
白子用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";
}
发布了89 篇原创文章 · 获赞 0 · 访问量 1606

猜你喜欢

转载自blog.csdn.net/qq_43410618/article/details/104606221