2020.11.22考试棋盘游戏题解

2020.11.22考试棋盘游戏题解

题目

【问题描述】
在一个 4x4 的棋盘上有 8 个黑棋和 8 个白棋,当且仅当两个格子有公共边时,这两个格
子上的棋是相邻的。移动棋子的规则是交换相邻的两个棋子。现在给出一个初始棋盘和一个
最终棋盘,要求你找出一个最短的移动序列使初始棋盘变为最终棋盘。
【输入】
第一到第四行每行 4 个数字(1 或者 0),描述初始棋盘。
接着是一个空行。
第六道第九行每行 4 个数字,描述最终棋盘。
【输出】
输出文件的第一行是一个整数 n,表示最少的移动步数。

思路

状态压缩矩阵存储成数字,能减少空间分配,哈希转化,BFS扩展判断下边和右边即可,因为这样所有点都可以扩展到。

代码实现

#include<bits/stdc++.h>
using namespace std;

const int maxn=65536+10;
char m[10][10];
int s,e;
queue<int>q;
int op[maxn];
bool vis[maxn];
//矩阵变数字
inline int h(char a[][10]){
	int ans=0;
	for(int i=0;i<4;i++){
		for(int j=0;j<4;j++){
			ans<<=1;
			ans|=(a[i][j]-'0');
		}
	}
	return ans;
} 
int main(){
	for(int i=0;i<4;i++)scanf("%s",m[i]);
	s=h(m);
	//printf("s %d\n",s);
	q.push(s);
	vis[s]=true;
	getchar();
	for(int i=0;i<4;i++)scanf("%s",m[i]);
	e=h(m);
	//printf("e %d\n",e);
	//BFS
	while(!q.empty()){
		int t=q.front();
		//printf("%d\n",t);
		q.pop();
		if(t==e){
			printf("%d\n",op[t]);
			return 0;
		}
		int t2=t;//防止变化带来的更改
		//反向数字变矩阵
		for(int i=3;i>=0;i--){
			for(int j=3;j>=0;j--) {
				if((t2&1)==0)m[i][j]='0';
				else m[i][j]='1';
				t2>>=1;
			}
		}
		//矩阵扩展
		for(int i=0;i<4;i++){
			for(int j=0;j<4;j++){
				//右
				if(j<3&&m[i][j]!=m[i][j+1]){
					swap(m[i][j],m[i][j+1]);
					int l=h(m);
					swap(m[i][j],m[i][j+1]); 
					if(!vis[l]){
						vis[l]=true;
						q.push(l);
						op[l]=op[t]+1;
					}
				}
				//下
				if(i<3&&m[i][j]!=m[i+1][j]){
					swap(m[i][j],m[i+1][j]);
					int l=h(m);
					swap(m[i][j],m[i+1][j]);
					if(!vis[l]){
						vis[l]=true;
						q.push(l);
						op[l]=op[t]+1;
					}
				}
			}
		}
	}
	return 0;
} 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

materialistOier

我只是一名ssfoier

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值