版权声明:那个,最起码帮我加点人气吧,署个名总行吧 https://blog.csdn.net/qq_41670466/article/details/84110090
题意大致就是给你一个3X3的矩阵,你要把矩阵转换成12345678的形式,在矩阵中是有一个空缺处可以供你移动滑块的,问你是否可以把给你的矩阵转换成12345678的形式,算了题意自己去看吧,有图更加直接
思路:这里主要考虑这几个方面:第一个如何判断经过一定转换的矩阵是规范矩阵?这里就用到了康拓展开,通过康拓展开来把当前的矩阵转换为一个数值,(哈希的思想)然后去参考是否和规范矩阵的康拓展卡的哈希值一样,如果一样那么就代表成功。然后就是如何判断这个矩阵是不可以解决的矩阵:由题意可得如果两个数交换那么这个矩阵就为不可解决的矩阵,于是我们只要判断这个矩阵的逆序数就好,如果逆序数为偶数个,那么可以解决,如果为奇数,则不可解决,输出unsolvable,同时为了以防万一在bfs判定时如果也不能找到答案,也输出不可解决。
代码:
#include<string>
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 5e5 + 10;
int vis[maxn];
int vis2[maxn];
char d[10] = { "udlr" }, d2[10] = { "durl" };
int dir[4] = { -3,3,-1,1 };
int ha[9] = { 40320,5040,720,120,24,6,2,1,1 };
string a, b = "123456780";
struct node
{
int num;
char ch;
}pre[maxn];
struct node2
{
int num;
string s;
}e;
void show(int x)
{
if (pre[x].num == -1)
return;
show(pre[x].num);
printf("%c", pre[x].ch);
}
int getha(string s)
{
int sum = 0;
for (int i = 0; i < 9; i++)
{
int k = 0;
for (int j = i + 1; j < 9; j++)
{
if (s[j] < s[i])k++;
}
sum+= k * ha[i];
}
return sum;
}
void bfs()
{
int q = getha(e.s);
queue<node2>q1;
queue<node2>q2;
vis[q] = 1;
node2 f,g;
f.s = b;
f.num = 8;
int p = getha(f.s);
int x,k;
vis2[p] = 2;
pre[1].num = -1;
pre[2].num = -1;
int num = 2;
q1.push(e);
q2.push(f);
while (!q1.empty() && !q2.empty())
{
f = q1.front();
q1.pop();
p = getha(f.s);
if (vis2[p])
{
show(vis[p]);
k = vis2[p];
while (pre[k].num != -1)
{
printf("%c", pre[k].ch);
k = pre[k].num;
}
printf("\n");
return;
}
for (int i = 0; i < 4; i++)
{
if (i == 0 && f.num < 3) continue;
if (i == 1 && f.num > 5) continue;
if (i == 2 && f.num % 3 == 0) continue;
if (i == 3 && f.num % 3 == 2) continue;
x = f.num + dir[i];
g = f;
swap(g.s[f.num], g.s[x]);
q = getha(g.s);
if (vis[q]) continue;
vis[q] = ++num;
g.num = x;
pre[num].num = vis[p];
pre[num].ch = d[i];
q1.push(g);
}
f = q2.front();
q2.pop();
p = getha(f.s);
if (vis[p])
{
show(vis[p]);
k = vis2[p];
while (pre[k].num != -1)
{
printf("%c", pre[k].ch);
k = pre[k].num;
}
printf("\n");
return;
}
for (int i = 0; i < 4; i++)
{
if (i == 0 && f.num < 3) continue;
if (i == 1 && f.num > 5) continue;
if (i == 2 && f.num % 3 == 0) continue;
if (i == 3 && f.num % 3 == 2) continue;
x = f.num + dir[i];
g = f;
swap(g.s[f.num], g.s[x]);
q = getha(g.s);
if (vis2[q]) continue;
vis2[q] = ++num;
g.num = x;
pre[num].num = vis2[p];
pre[num].ch = d2[i];
q2.push(g);
}
}
printf("unsolvable\n");
}
int main()
{
while (getline(cin, a))
{
int n, k = 0;
n = a.size();
e.s = "";
for (int i = 0, j = 0; i < n; i++)
{
if (a[i] != ' ')
{
if (a[i] == 'x')
{
e.num = j;
e .s+= '0';
}
else
e.s += a[i];
j++;
}
}
for (int i = 0; i < 9; i++)
{
if (e.s[i] == '0') continue;
for (int j = 0; j < i; j++)
{
if (e.s[j] == '0') continue;
if (e.s[j] > e.s[i]) k++;
}
}
memset(vis2, 0, sizeof(vis2));
memset(vis, 0, sizeof(vis));
if (k & 1) printf("unsolvable\n");
else
bfs();
}
system("pause");
return 0;
}