1.全排列 + bfs
#include<stdio.h>
#include<queue>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 4e5 + 8;
int num[N], v[N], len;
int res = 123804765;
int changelo[9][4] = { {-1,-1,3,1},{-1,0,4,2},{-1,1,5,-1},
{0,-1,6,4},{1,3,7,5},{2,4,8,-1},
{3,-1,-1,7},{4,6,-1,8},{5,7,-1,-1}
};
bool vn[9];
char ans[11];
int s;
void pailie(int k)
{
for (int i = 0; i < 9; i++)
{
if (!vn[i])
{
ans[k] = i + '0';
vn[i] = 1;
if (k == 8)
{
sscanf(ans, "%d", &num[len++]);
}
else
pailie(k + 1);
vn[i] = 0;
}
}
}
void swapch(char* a, int p1, int p2)
{
char b = a[p1];
a[p1] = a[p2];
a[p2] = b;
}
struct node
{
int numn;
int pos;
int val;
};
bool flag;
void bfs(int n, int p)
{
queue<node> q;
q.push({ n, p, 0 });
int p1 = lower_bound(num, num + len, n) - num;
v[p1] = 1;
while (!q.empty())
{
node no = q.front();
q.pop();
char cur[11];
sprintf(cur, "%09d", no.numn);
int p2 = no.pos;
for (int i = 0; i < 4; i++)
{
if (changelo[p2][i] != -1)
{
swapch(cur, p2, changelo[p2][i]);
int n1; sscanf(cur, "%d", &n1);
if (n1 == res)
{
printf("%d", no.val + 1);
flag = true;
return;
}
int k = lower_bound(num, num + len, n1) - num;
if (!v[k])
{
v[k] = 1;
q.push({ n1, changelo[p2][i], no.val + 1 });
}
swapch(cur, p2, changelo[p2][i]);
}
}
}
}
int main()
{
char a[11]; int sp;
cin >> a;
for (int i = 0; i < 9; i++)
if (a[i] == '0')
{
sp = i;
break;
}
sscanf(a, "%d", &s);
if (s == res)
{
printf("0"); return 0;
}
pailie(0);
bfs(s, sp);
if (!flag) printf("unsolvable");
return 0;
}
2.map + bfs
#include<stdio.h>
#include<queue>
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
const int N = 4e5 + 8;
map<string, int> num;
string res = "123804765";
int changelo[9][4] = { {-1,-1,3,1},{-1,0,4,2},{-1,1,5,-1},
{0,-1,6,4},{1,3,7,5},{2,4,8,-1},
{3,-1,-1,7},{4,6,-1,8},{5,7,-1,-1}
};
string s;
void swapch(string& a, int p1, int p2)
{
char b = a[p1];
a[p1] = a[p2];
a[p2] = b;
}
struct node
{
string numn;
int pos;
int val;
};
bool flag;
void bfs(string n, int p)
{
queue<node> q;
q.push({ n, p, 0 });
num[n] = 1;
while (!q.empty())
{
node no = q.front();
q.pop();
string cur = no.numn;
int p2 = no.pos;
for (int i = 0; i < 4; i++)
{
if (changelo[p2][i] != -1)
{
swapch(cur, p2, changelo[p2][i]);
if (cur == res)
{
printf("%d", no.val + 1);
flag = true;
return;
}
if (!num[cur])
{
num[cur] = 1;
q.push({ cur, changelo[p2][i], no.val + 1 });
}
swapch(cur, p2, changelo[p2][i]);
}
}
}
}
int main()
{
int sp;
cin >> s;
for (int i = 0; i < 9; i++)
if (s[i] == '0')
{
sp = i;
break;
}
if (s == res)
{
printf("0"); return 0;
}
bfs(s, sp);
if (!flag) printf("unsolvable");
return 0;
}
3.双向广搜 + map
#include<stdio.h>
#include<queue>
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
const int N = 4e5 + 8;
map<string, int> num;
map<string, int> val;
string res = "123804765";
int changelo[9][4] = { {-1,-1,3,1},{-1,0,4,2},{-1,1,5,-1},
{0,-1,6,4},{1,3,7,5},{2,4,8,-1},
{3,-1,-1,7},{4,6,-1,8},{5,7,-1,-1}
};
string s;
void swapch(string& a, int p1, int p2)
{
char b = a[p1];
a[p1] = a[p2];
a[p2] = b;
}
struct node
{
string numn;
int pos;
};
bool flag;
void dbfs(string n, int p)
{
queue<node> q;
q.push({ n, p});
q.push({ res, 4});
num[n] = 1; num[res] = 2;
while (!q.empty())
{
node no = q.front();
q.pop();
string cur = no.numn;
int p2 = no.pos;
string now = cur;
for (int i = 0; i < 4; i++)
{
if (changelo[p2][i] != -1)
{
swapch(cur, p2, changelo[p2][i]);
if (num[cur] + num[now] == 3)
{
printf("%d", val[now] + 1 + val[cur]);
flag = true;
return;
}
if (!num[cur])
{
num[cur] = num[now];
q.push({ cur, changelo[p2][i]});
val[cur] = val[now] + 1;
}
swapch(cur, p2, changelo[p2][i]);
}
}
}
}
int main()
{
int sp;
cin >> s;
for (int i = 0; i < 9; i++)
if (s[i] == '0')
{
sp = i;
break;
}
if (s == res)
{
printf("0"); return 0;
}
dbfs(s, sp);
if (!flag) printf("unsolvable");
return 0;
}
4.A* + map
#include<stdio.h>
#include<queue>
#include<iostream>
#include<algorithm>
#include<map>
#include<cmath>
using namespace std;
const int N = 4e5 + 8;
map<string, int> num;
string des = "123804765";
int dpos[10] = { 4,0,1,2,5,8,7,6,3,0 };
int changelo[9][4] = { {-1,-1,3,1},{-1,0,4,2},{-1,1,5,-1},
{0,-1,6,4},{1,3,7,5},{2,4,8,-1},
{3,-1,-1,7},{4,6,-1,8},{5,7,-1,-1}
};
string s;
void swapch(string& a, int p1, int p2)
{
char b = a[p1];
a[p1] = a[p2];
a[p2] = b;
}
struct node
{
string numn;
int pos;
int step;
int cost;
bool operator < (const node& other) const
{
return cost > other.cost;
}
node(string n, int p, int s)
{
numn = n, pos = p, step = s;
setCost();
}
void setCost()
{
int c = 0;
for (int i = 0; i < 9; i++)
c += abs(i % 3 - dpos[numn[i]] % 3) + abs(i / 3 - dpos[numn[i]] / 3);
cost = step + c;
}
};
bool flag;
void bfs(string n, int p)
{
priority_queue<node> q;
q.push({ n, p, 0 });
num[n] = 1;
while (!q.empty())
{
node no = q.top();
q.pop();
string cur = no.numn;
int p2 = no.pos;
for (int i = 0; i < 4; i++)
{
if (changelo[p2][i] != -1)
{
swapch(cur, p2, changelo[p2][i]);
if (cur == des)
{
printf("%d", no.step + 1);
flag = true;
return;
}
if (!num[cur])
{
num[cur] = 1;
q.push({ cur, changelo[p2][i], no.step + 1 });
}
swapch(cur, p2, changelo[p2][i]);
}
}
}
}
int main()
{
int sp;
cin >> s;
for (int i = 0; i < 9; i++)
if (s[i] == '0')
{
sp = i;
break;
}
if (s == des)
{
printf("0"); return 0;
}
bfs(s, sp);
if (!flag) printf("unsolvable");
return 0;
}
5.IDA* + map
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<map>
#include<cmath>
using namespace std;
const int N = 4e5 + 8;
map<string, int> num;
string des = "123804765";
int changelo[9][4] = { {-1,-1,3,1},{-1,0,4,2},{-1,1,5,-1},
{0,-1,6,4},{1,3,7,5},{2,4,8,-1},
{3,-1,-1,7},{4,6,-1,8},{5,7,-1,-1}
};
string s;
bool flag;
void swapch(string& a, int p1, int p2)
{
char b = a[p1];
a[p1] = a[p2];
a[p2] = b;
}
bool test(int dep, string n, int ddep)
{
int cnt = 0;
for (int i = 0; i < 9; i++)
if (n[i] != des[i])
{
cnt++;
if (cnt + dep > ddep)
return false;
}
return true;
}
void dfs(int dep, string n, int p, int ddep)
{
if (!test(dep, n, ddep)) return;
if (n == des)
{
printf("%d", dep);
flag = true;
return;
}
num[n] = 1; string cur = n;
for (int i = 0; i < 4; i++)
{
if (changelo[p][i] != -1)
{
swapch(cur, p, changelo[p][i]);
if (!num[cur])
{
num[cur] = 1;
if(test(dep + 1, cur, ddep) && !flag) dfs(dep + 1, cur, changelo[p][i], ddep);
num[cur] = 0;
}
swapch(cur, p, changelo[p][i]);
}
}
}
int main()
{
int sp;
cin >> s;
for (int i = 0; i < 9; i++)
if (s[i] == '0')
{
sp = i;
break;
}
if (s == des)
{
printf("0"); return 0;
}
int k = 0;
while (++k)
{
dfs(0, s, sp, k);
if (flag) break;
}
return 0;
}