问题 1426: [蓝桥杯][历届试题]九宫重排(map处理)

版权声明:本文为博主原创文章,转载请附带博主链接。 https://blog.csdn.net/pashuihou/article/details/88382521

【题目链接】
http://www.dotcpp.com/oj/problem1426.html

题目意思

如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。

解题思路

用BFS非常容易求出最小步数,但是怎么标记图呢?看了一些用二维标记的,感觉麻烦。所以把图变成字符串,用map处理。需要注意的是每排的最前面一个没办法到前一排最后一个。同理最后一个一样。

代码部分

/*************
*题意:略
*链接:http://www.dotcpp.com/oj/problem1426.html
*思路:把二维图转换成字符串处理,用map标记 
*************/
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
#define ll long long
map<string,int>M; //标记 
int dir[4]={-1,1,-3,3};//方位 
struct node
{
	char str[15];
	ll step;
	int point; 
}start,ed;
bool ok(node tt)
{
	if (M[tt.str]++ == 0)
		return true;
	else return false;
}
ll Bfs()
{
	queue<node>q;
	q.push(start);
	while (!q.empty ())
	{
		node t = q.front();
		q.pop();
		if (strcmp(t.str,ed.str) == 0)
			return t.step;
		for (int i = 0; i < 4; i++)
		{
			//每排最后和最前不能加减1 
			if (i == 0 && t.point%3 == 0) continue; 
			if (i == 1 && t.point%3 == 2) continue;
			node tt = t;
			tt.step++;
			tt.point += dir[i];
			if (tt.point >= 0 && tt.point < 9)
			{
				//先交换再判断是否出现过。 
				swap(tt.str[tt.point],tt.str[t.point]);
				if (ok(tt))
				{
					q.push(tt);
				}
			}
		}
	}
	return -1;
}
int main()
{
	scanf("%s %s",start.str,ed.str);
	for (int i = 0; i < 9; i++)
		if (start.str[i] == '.')
			start.point = i;
	start.step = 0;
	M[start.str]++;
	cout<<Bfs()<<endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/pashuihou/article/details/88382521
今日推荐