蓝桥杯 九宫重排
C++
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};
int factor[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800};
bool vis[400000];
struct Node {
int x, y, st, pos, step;
string s;
Node() {}
Node(int _x, int _y, int _pos) {
x = _x;
y = _y;
pos = _pos;
}
};
int cantor(string s) {
int ans = 0;
for(int i = 0; i < 8; i ++) {
int num = 0;
for(int j = i + 1; j <= 8; j ++) {
if(s[j] < s[i]) num ++;
}
ans = ans + num * factor[8 - i];
}
return ans;
}
int bfs(string s, string end) {
Node now, nxt;
now.s = s;
now.st = cantor(now.s);
for(int i = 0; i < 3; i ++) {
for(int j = 0; j < 3; j ++) {
if(now.s[i * 3 + j] == '.') {
now.x = i;
now.y = j;
now.pos = i * 3 + j;
}
}
}
now.step = 0;
queue<Node> q;
q.push(now);
vis[now.st] = true;
int ans = cantor(end);
while(!q.empty()) {
now = q.front();
q.pop();
if(ans == now.st) {
return now.step;
}
for(int i = 0; i < 4; i ++) {
int tx = now.x + dx[i];
int ty = now.y + dy[i];
int tpos = tx * 3 + ty;
if(tx >= 0 && tx < 3 && ty >= 0 && ty < 3) {
nxt.s = now.s;
swap(nxt.s[now.pos], nxt.s[tpos]);
nxt.st = cantor(nxt.s);
if(!vis[nxt.st]) {
nxt.x = tx;
nxt.y = ty;
nxt.pos = tpos;
nxt.step = now.step + 1;
vis[nxt.st] = true;
q.push(nxt);
}
}
}
}
return -1;
}
int main()
{
string a, b;
cin >> a >> b;
cout << bfs(a, b) << endl;
}
八数码问题
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
int dx[] = {1, -1, 0, 0}; // x方向
int dy[] = {0, 0, 1, -1}; // y方向
// 阶乘
int factor[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800};
bool vis[400000]; // 标记
struct Node{
int x, y, st, pos, step;
string s;
Node() {}
Node(int _x, int _y, int _pos) {
x = _x;
y = _y;
pos = _pos;
}
};
// 康托展开
int cantor(string s) {
int ans = 0;
for(int i = 0; i < 8; i ++) {
int num = 0;
for(int j = i + 1; j <= 8; j ++){
if(s[j] < s[i]) num ++;
}
ans = ans + num * factor[8 - i];
}
return ans;
}
// 宽度优先搜素
int bfs(string s, string end) {
Node now, nxt;
now.s = s;
now.st = cantor(now.s);
for(int i = 0; i < 3; i ++) {
for(int j = 0; j < 3; j ++) {
if(now.s[i * 3 + j] == '0') {
now.x = i;
now.y = j;
now.pos = i * 3 + j;
}
}
}
now.step = 0;
queue<Node> q;
q.push(now);
vis[now.st] = true;
int ans = cantor(end);
while(!q.empty()) {
now = q.front();
q.pop();
if(ans == now.st) {
return now.step;
}
for(int i = 0; i < 4; i ++) {
int tx = now.x + dx[i];
int ty = now.y + dy[i];
int tpos = tx * 3 + ty;
if(tx >= 0 && tx < 3 && ty >= 0 && ty < 3) {
nxt.s = now.s;
swap(nxt.s[now.pos], nxt.s[tpos]);
nxt.st = cantor(nxt.s);
if(!vis[nxt.st]) {
nxt.x = tx;
nxt.y = ty;
nxt.pos = tpos;
nxt.step = now.step + 1;
vis[nxt.st] = true;
q.push(nxt);
}
}
}
}
return -1;
}
int main()
{
string t;
while(cin >> t) {
string a, b;
a += t;
for(int i = 0; i < 2; i ++) cin >> t, a += t;
cout << endl;
for(int i = 0; i < 3; i ++) cin >> t, b += t;
cout << endl;
cout << bfs(a, b) << endl;
}
}
/*
123
456
780
123
046
758
135
246
780
467
581
230
264
137
058
815
736
402
*/