[C]黑白子交换之递归解法{含所有走法及最少步数走法}

原题目如下:
题目
递归解法:
[输出所有解法,以及最少步数解法]

#include <stdio.h>
char space[7] = { -3,-2,-1,0,1,2,3 };//棋盘,负数白棋,正数黑棋,0空格
int memory[1000];//行走历史记录
int memory_p = 0;//待记录的一步应该记录在第几个元素
int memory_run = 0;//已经行走步数
int min_run = 1000;//最少行走步数
int min_memory[1000];//最少行走步数历史记录
int number = 1;//走法总数
void run() {
	int i;
	for (i = 0; i < 7; ++i) {//从左往右扫一遍,看谁能走
		if (space[i] < 0) {//如果是白棋
			if (i == 6 || i == 5 && space[6])
				continue;//遇到了边界情况
			if (space[i + 1] == 0) {//如果右边一点是空的就走
				memory[memory_p++] = space[i];//追加历史记录
				++memory_run;//追加步数
				space[i + 1] = space[i];//走了
				space[i] = 0;
				run();
				//回退
				space[i] = space[i + 1];
				space[i + 1] = 0;
				--memory_run;
				--memory_p;
			}
			else if (space[i + 2] == 0) {//如果能跳就跳
				memory[memory_p++] = space[i];//追加历史记录
				++memory_run;//追加步数
				space[i + 2] = space[i];//走了
				space[i] = 0;
				run();
				//回退
				space[i] = space[i + 2];
				space[i + 2] = 0;
				--memory_run;
				--memory_p;
			}
		}
		else if (space[i] > 0) {//黑棋
			if (i == 0 || i == 1 && space[0])
				continue;//遇到了边界情况
			if (space[i - 1] == 0) {//如果左边一点是空的就走
				memory[memory_p++] = space[i];//追加历史记录
				++memory_run;//追加步数
				space[i - 1] = space[i];//走了
				space[i] = 0;
				run();
				//回退
				space[i] = space[i - 1];
				space[i - 1] = 0;
				--memory_run;
				--memory_p;
			}
			else if (space[i - 2] == 0) {//如果能跳就跳
				memory[memory_p++] = space[i];//追加历史记录
				++memory_run;//追加步数
				space[i - 2] = space[i];//走了
				space[i] = 0;
				run();
				//回退
				space[i] = space[i - 2];
				space[i - 2] = 0;
				--memory_run;
				--memory_p;
			}
			
		}
	}
	//到这里就意味着一步都走不了了,所以开始测试胜利与否
	if (space[0] + space[1] + space[2] == 6 && space[4] + space[5] + space[6] == -6) {//如果胜利就开始记录

		printf("第%d种走法消耗的步数:%d\n", number++, memory_run);
		printf("过程:");
		for (int i = 0; i < memory_p; ++i) {
			printf("%d ", memory[i]);
		}
		printf("\n");

		if (memory_run < min_run) {
			min_run = memory_run;
			for (i = 0; i < memory_p; ++i)
				min_memory[i] = memory[i];
		}
	}
}
int main() {
	run();
	printf("共%d种走法\n", number - 1);
	printf("================================\n");
	printf("其中最少步数:%d\n", min_run);
	printf("过程:");
	for (int i = 0; i < min_run;++i) {
		printf("%d ", min_memory[i]);
	}
}
/*最少步数试走
-3 -2 -1 0 1 2 3
-3 -2 0 -1 1 2 3
-3 -2 1 -1 0 2 3
-3 -2 1 -1 2 0 3
-3 -2 1 0 2 -1 3
-3 0 1 -2 2 -1 3
0 -3 1 -2 2 -1 3
1 -3 0 -2 2 -1 3
1 -3 2 -2 0 -1 3
1 -3 2 -2 3 -1 0
1 -3 2 -2 3 0 -1
1 -3 2 0 3 -2 -1
1 0 2 -3 3 -2 -1
1 2 0 -3 3 -2 -1
1 2 3 -3 0 -2 -1
1 2 3 0 -3 -2 -1
成功
*/

结果:
[数字为应该移动的棋子,由于每颗棋子走的时候,落点唯一,故不需要展示从哪走到哪,只需展示要走哪颗棋子]
结果
Tip:只有这两种走法能走通,而且两种走法很对称…

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值