#include <iostream>
#include <fstream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 5;
const int M = 100;
const int HASHSIZE = 10000007;
const int QUEUELEN = 100000;
struct Node {
int step;
int m[N][N];
int ans[M];
};
int src[N][N];
int m;
int head[HASHSIZE];
int next[QUEUELEN];
Node q[QUEUELEN];
void bfs();
int hash(Node node);
int insert(int v);
bool check(Node node);
void print(Node node);
int main()
{
int t;
int count;
#ifndef ONLINE_JUDGE
ifstream cin("d:\\OJ\\uva_in.txt");
#endif // ONLINE_JUDGE
cin >> t;
while (t--) {
memset(src, 0x00, sizeof(src));
cin >> m;
if (m < 1 && m > 15 ) {
cout << "IMPOSSIBLE" << endl;
continue;
}
count = 1;
for (int i = 0; i < N; i++) {
for (int j = 0; j <= i; j++) {
if (count != m)
src[i][j] = count;
count++;
}
}
bfs();
}
return 0;
}
void bfs()
{
int front = 0, rear = 0;
Node node, newNode;
bool flag;
int step;
memset(&node, 0x00, sizeof(Node));
memset(head, -1, sizeof(head));
memcpy(node.m, src, sizeof(src));
q[rear++] = node;
while (front < rear) {
Node tmp = q[front++];
if (check(tmp)) {
int step = tmp.step;
cout << step << endl;
for (int i = 0; i < step; i++) {
if (i)
cout << " ";
cout << tmp.ans[2 * i] << " " << tmp.ans[2 * i + 1];
}
cout << endl;
return;
}
for (int i = 0; i < N; i++) {
for (int j = 0; j <= i; j++) {
if (tmp.m[i][j] == 0) {
//水平方向
flag = true;
int jj = j + 1;
if (jj > i)
flag = false;
if (flag && tmp.m[i][jj] == 0)
flag = false;
while (flag && jj <= i && tmp.m[i][jj] != 0) {
if (jj - j >= 2) {
newNode = tmp;
swap(newNode.m[i][jj], newNode.m[i][j]);
fill(&(newNode.m[i][j + 1]), &(newNode.m[i][jj]), 0x00);
step = newNode.step;
newNode.ans[2 * step] = (i + 1) * i / 2 + jj + 1;
newNode.ans[2 * step + 1] = (i + 1) * i / 2 + j + 1;
newNode.step++;
q[rear] = newNode;
if (insert(rear)) rear++;
}
jj++;
}
if (flag && jj - 1 - j < 2)
flag = false;;
if (flag ) {
newNode = tmp;
swap(newNode.m[i][j], newNode.m[i][jj - 1]);
fill(&(newNode.m[i][j + 1]), &(newNode.m[i][jj]), 0x00);
step = newNode.step;
newNode.ans[2 * step] = (i + 1) * i / 2 + jj;
newNode.ans[2 * step + 1] = (i + 1) * i / 2 + j + 1;
newNode.step++;
q[rear] = newNode;
if (insert(rear)) rear++;
}
//竖直方向
flag = true;
int ii = i + 1;
//cout << "ii1:" << ii << endl;
if (ii >= N)
flag = false;
if (flag && tmp.m[ii][j] == 0)
flag = false;;
while (flag && ii < N && tmp.m[ii][j] != 0) {
if (ii - i >= 2) {
newNode = tmp;
swap(newNode.m[i][j], newNode.m[ii][j]);
for (int k = i + 1; k < ii; k++) {
newNode.m[k][j] = 0;
}
step = newNode.step;
newNode.ans[2 * step] = (ii + 1) * ii / 2 + j + 1;
newNode.ans[2 * step + 1] = (i + 1) * i / 2 + j + 1;
newNode.step++;
q[rear] = newNode;
if (insert(rear)) rear++;
}
ii++;
}
ii--;
if (flag && ii - i < 2)
flag = false;
if (flag) {
newNode = tmp;
swap(newNode.m[i][j], newNode.m[ii][j]);
for (int k = i + 1; k < ii; k++)
newNode.m[k][j] = 0;
step = newNode.step;
newNode.ans[2 * step] = (ii + 1) * ii / 2 + j + 1;
newNode.ans[2 * step + 1] = (i + 1) * i / 2 + j + 1;
newNode.step++;
q[rear] = newNode;
if (insert(rear)) rear++;
}
//对角线方向
flag = true;
ii = i + 1;
jj = j + 1;
if (ii >= N)
flag = false;
if (flag && tmp.m[ii][jj] == 0)
flag = false;
while (flag &&ii < N && tmp.m[ii][jj] != 0) {
if (ii - i >= 2) {
newNode = tmp;
swap(newNode.m[i][j], newNode.m[ii][jj]);
for (int k = i + 1, p = j + 1; k < ii; k++, p++) {
newNode.m[k][p] = 0;
}
step = newNode.step;
newNode.ans[2 * step] = (ii + 1) * ii / 2 + jj + 1;
newNode.ans[2 * step + 1] = (i + 1) * i / 2 + j + 1;
newNode.step++;
q[rear] = newNode;
if (insert(rear)) rear++;
}
ii++, jj++;
}
ii--, jj--;
if (flag && ii - i < 2)
flag = false;
if (flag) {
newNode = tmp;
swap(newNode.m[i][j], newNode.m[ii][jj]);
for (int k = i + 1, p = j + 1; k < ii; k++, p++)
newNode.m[k][p] = 0;
step = newNode.step;
newNode.ans[2 * step] = (ii + 1) * ii / 2 + jj + 1;
newNode.ans[2 * step + 1] = (i + 1) * i / 2 + j + 1;
newNode.step++;
q[rear] = newNode;
if (insert(rear)) rear++;
}
} else {
//水平方向
flag = true;
int jj = j + 1;
if (jj > i)
flag = false;;
if (flag && tmp.m[i][jj] == 0)
flag = false;
while (flag && jj <= i && tmp.m[i][jj] != 0) jj++;
if (flag && jj > i)
flag = false;
if (flag && jj - j < 2)
flag = false;
if (flag) {
newNode = tmp;
swap(newNode.m[i][j], newNode.m[i][jj]);
fill(&newNode.m[i][j + 1], &newNode.m[i][jj], 0x00);
int step = newNode.step;
newNode.ans[2 * step] = (i + 1) * i / 2 + j + 1;
newNode.ans[2 * step + 1] = (i + 1) * i / 2 + jj + 1;
newNode.step++;
q[rear] = newNode;
if (insert(rear)) rear++;
}
//竖直方向
flag = true;
int ii = i + 1;
if (ii >= N)
flag = false;
if (flag && tmp.m[ii][j] == 0)
flag = false;
while (flag && ii < N && tmp.m[ii][j] != 0) ii++;
if (flag && ii >= N)
flag = false;
if (flag && ii - i < 2)
flag = false;
if (flag) {
newNode = tmp;
swap(newNode.m[i][j], newNode.m[ii][j]);
for (int k = i + 1; k < ii; k++)
newNode.m[k][j] = 0;
step = newNode.step;
newNode.ans[2 * step] = (i + 1) * i / 2 + j + 1;
newNode.ans[2 * step + 1] = (ii + 1) * ii / 2 + j + 1;
newNode.step++;
q[rear] = newNode;
if (insert(rear)) rear++;
}
//对角线方向
flag = true;
ii = i + 1;
jj = j + 1;
if (ii >= N)
flag = false;
if (flag && tmp.m[ii][jj] == 0)
flag = false;
while (flag && ii < N && tmp.m[ii][jj] != 0) ii++, jj++;
if (flag && ii >= N)
flag = false;
if (flag && ii - i < 2)
flag = false;
if (flag ) {
newNode = tmp;
swap(newNode.m[i][j], newNode.m[ii][jj]);
for (int k = i + 1, p = j + 1; k < ii; k++, p++)
newNode.m[k][p] = 0;
step = newNode.step;
newNode.ans[2 * step] = (i + 1) * i / 2 + j + 1;
newNode.ans[2 * step + 1] = (ii + 1) * ii / 2 + jj + 1;
newNode.step++;
q[rear] = newNode;
if (insert(rear)) rear++;
}
}
}
}
}
cout << "IMPOSSIBLE" << endl;
}
int hash(Node node)
{
int h = 0;
for (int i = 0; i < 5; i++) {
for (int j = 0; j <= i; j++) {
h = h * 10 + node.m[i][j];
}
}
return (h & 0x7fffffff) % HASHSIZE;
}
int insert(int v)
{
int h = hash(q[v]);
for (int u = head[h]; u != -1; u = next[u])
if (memcmp(q[u].m, q[v].m, sizeof(src)) == 0)
return 0;
next[v] = head[h];
head[h] = v;
return 1;
}
bool check(Node node)
{
int count = 1;
int cx, cy;
for (int i = 0; i < N; i++) {
for (int j = 0; j <= i; j++) {
if (count != m) {
if (node.m[i][j] != 0)
return false;
} else {
cx = i;
cy = j;
}
count++;
}
}
return node.m[cx][cy] != 0;
}
void print(Node node)
{
for (int i = 0; i < N; i++) {
for (int j = 0; j <= i; j++) {
cout << node.m[i][j] << " ";
}
cout << endl;
}
}
UVa1533 - Moving Pegs(错在什么地方)
最新推荐文章于 2021-03-17 23:01:38 发布