分治法 —— 黑白棋子移动
黑白棋子移动
- 题目描述
- 题意解读
- Code
- 结语
题目描述
有2n个棋子(n≥4)排成一行,开始位置为白子全部在左边,黑子全部在右边,如下图为n=5的情形:
○○○○○●●●●●
移动棋子的规则是:每次必须同时移动相邻的两个棋子,颜色不限,可以左移也可以右移到空位上去,但不能调换两个棋子的左右位置。每次移动必须跳过若干个棋子(不能平移),要求最后能移成黑白相间的一行棋子。如n=5时,成为:
○●○●○●○●○●
任务:编程打印出移动过程。
样例输入 Copy
7
样例输出 Copy
step 0:ooooooo*******--
step 1:oooooo--******o*
step 2:oooooo******--o*
step 3:ooooo--*****o*o*
step 4:ooooo*****--o*o*
step 5:oooo--****o*o*o*
step 6:oooo****--o*o*o*
step 7:ooo--***o*o*o*o*
step 8:ooo*o**--*o*o*o*
step 9:o--*o**oo*o*o*o*
step10:o*o*o*--o*o*o*o*
step11:--o*o*o*o*o*o*o*
题目链接 - 黑白棋子移动
题意解读
有2n个棋子(n≥4)排成一行 为什么n 至少要大于等于4呢?
我们再来看给出的样例,发现需要12步且每一步需要数字(%2d)来表示步骤的序号,我们可以发现都是两两交换,但是在4以及以后两两交换的方法和之前的交换不一样或者说无逻辑可言。
发现规律啦吧!那么该题是典型的分治策略,选择递归比较合适!
具体实现我们来看一下代码,嘿嘿!
Code
#include <iostream>
#include <cstdio>
#include <stdlib.h>
using namespace std;int n;//n == 4 是一个边界, n = 7 的问题可以转化n = 6 的问题,最后转化到n = 4 的问题
//分治也可以分层递进
//主要是要找准规律void print(char s[])
{for (int i = 0; i < 2 * n + 2; i++)printf("%c", s[i]);printf("\n");
}
void Swap(char s[], int i, int j)//两个的字符的交换
{char temp;temp = s[i];s[i] = s[j];s[j] = temp;temp = s[i + 1];s[i + 1] = s[j + 1];s[j + 1] = temp;
}
void fun(char a[],int m, int x)
{if (m == 4){//m= 4时把无规律的情况直接打印输出即可,最后结束递归printf("step%2d:", x++);Swap(a, 3, 8);print(a);printf("step%2d:", x++);Swap(a, 3, 7);print(a);printf("step%2d:", x++);Swap(a, 1, 7);print(a);printf("step%2d:", x++);Swap(a, 1, 6);print(a);printf("step%2d:", x++);Swap(a, 0, 6);print(a);return ;}else {// m != 4时,先进行两个字符的交换并打印,然后递归进入小规模问题中printf("step%2d:", x++);Swap(a, m - 1, 2 * m);print(a);printf("step%2d:", x++);Swap(a, m - 1, 2 * (m - 1));print(a);fun(a, m - 1, x);//进入下一层递归,问题规模变小直到m = 4}}int main ()
{char a[200];cin >> n;int i;for (i = 0; i < n; i++)a[i] = 'o';for (; i < 2 * n; i++)a[i] = '*';for (; i < 2 * n + 2; i++)a[i] = '-';//首先我们先输入n 以及 n个'o'和'*'以及 '-'printf("step%2d:", 0);print(a);//打印0步骤的状态,即初始状态fun(a, n, 1);//递归调用return 0;
}
结语
其实代码部分对逻辑的阐述已经一目了然啦!该题根本点在于能否发现n >= 4 的核心点
当然本人刚刚学的分治算法,水平低下,讲解不一定清晰明了!
此处附上视频链接地址,推荐看一看来加深分治算法的理解!
参考链接 :https://www.bilibili.com/video/BV1kp4y197h7
分治法 —— 黑白棋子移动相关推荐
- 代码分析+原理图解——棋盘覆盖问题-分治法
上算法课时,老师以文字+代码的方式讲了这道题,然而有很多同学反映听的不是太懂, 我们接触事物最直观的就是以图片理解,因此我尝试使用图解法来帮助大家理解. 问题描述: 注意:分治法最核心的一点是:分 ...
- 棋盘覆盖-分治法(代码实现)
这是棋盘覆盖的代码实现,至于原理,请参考我的上一篇博客:棋盘覆盖问题-分治法 实现的效果如下: 或者如下: 其中0表示递归过程中标记的所有奇异点 实现代码如下: //棋盘大小size, 奇异点的坐标( ...
- 【分治法】棋盘覆盖问题java实现
文章目录 问题描述 问题分析 算法设计 java代码 问题描述 在一个2k × 2k个放个中,恰好只有一个方格是残缺的.也就是在这个棋盘中有一个方格与其它的格子不同, 我们称这种棋盘为残缺棋盘. 下图 ...
- matlab显示黑白棋子,围棋—暗藏在黑白棋子中的大智慧 你了解吗?
文章来源:腾讯少儿围棋 那些暗藏在围棋黑白棋子之间的大智慧,是我们一定不能忽视的.好多家长觉得围棋不适合太小的孩子学,主要有两个原因.第一点就是,觉得围棋的难度过大,对于孩子来说,只能算是一个单纯的娱 ...
- 算法设计思想(4)— 分治法
1. 分治法概念 分治,顾名思义,分而治之. 具体来说,它先将一个难以直接解决的大问题,分割成一些可以直接解决的小问题.如果分割后的问题仍然无法直接解决,那么就继续递归地分割,直到每个小问题都可解. ...
- 动态规划和分治法,贪心算法以及递归的再一次深刻理解和体会
每次体会算法都有新的感觉,刷题越多,对算法的理解感觉也就越深刻. 下面我们来重新体会下分治法,动态规划,贪心法,递归的理解. 1.分治法: 将问题分成单独的阶段,每个阶段互相不干扰很独立,如10米长的 ...
- LeetCode 23. Merge k Sorted Lists--Python解法--优先队列,分治法
题目地址:Merge k Sorted Lists - LeetCode Merge k sorted linked lists and return it as one sorted list. A ...
- Hanoi塔(分治法的应用)
1.分治法 分治法的设计思想是将一个难以直接解决的大问题分解成一些规模较小的相同问题,以便各个击破,分而治之. 一般来说,分治算法在每一层递归上都有3个步骤: (1)分解:将问题分解成一系列子问题. ...
- 从合并排序算法看“分治法”
本文内容 分治策略 分治步骤 从合并排序看"分治策略" 分治策略 分治法(divide-and-conquer),"分治法策略"是一种很重要的算法.顾名思义,& ...
最新文章
- python-opencv 常用工具总结
- 理科生用创意毁灭世界,爆笑!
- JavaScript学习 九、事件
- 【VMCloud云平台】SCDPM(六)额外篇-DPM备份到Azure上
- MVC传递Model
- YzmCMS轻量级开源CMS v6.2
- so easy 的弹出层——使用jquery
- win7更改计算机名后桌面壁纸,win7桌面壁纸不能更换怎么办-处理win7桌面壁纸无法更换的方案 - 河东软件园...
- Java实现微信授权登录
- linux发送邮件mail详解
- 图神经网络(ICML2022)
- 2021年中国互联网企业100强出炉(附全名单)
- 微信公共号开发教程java版——获取用户基本信息(UnionID机制)(七)
- wagon-maven-plugin插件实现自动化构建部署到服务器
- STM32实现DAC功能输出音频波形
- 字符串操作函数strstr
- 03-OSPF OE2和OE1外部路由详解
- 反色(顺序)C C++
- 快手只发作品不直播的赚钱方法
- 在oracle符号,学在oracle数据库中插入特殊符号