标签:sicily
Time Limit: 2 secs, Memory Limit: 256 MB
Nine tiles, each with a number from 1 to 9 on it, are packed into a 3 by 3 frame. Your task is to arrange the tiles so that they are ordered as:
Write a program to find the minimum number of steps.
Input contains multiple test cases.
Output the minimum number of steps on a single line for each test case.
1 2 3 4 5 6 7 8 9 4 1 3 5 2 6 7 8 9
0 3
每周一赛:2010中山大学新手赛
相当好的一道题,bfs + 康托,方法是逆序思维,将123456789不断转化为各种排列形式,并记录步数;
但是有个麻烦,想要这样过,就必须用数组存步数,数组是开不了那么大的,这就要用到康托,其实康托就是把排列组合与实数之间建立映射;
#include <iostream>
#include <queue>
#include <stdio.h>
using namespace std;
int fac[9] = {40320, 5040, 720, 120, 24, 6, 2, 1, 1};//阶乘的值,用来康托的
int ans[362880 + 1];//存放答案
int make_num(int a[]) {//将数字数组转化为数字
int sum = 0;
for (int i = 0; i < 9; i++) {
sum = sum * 10 + a[i];
}
return sum;
}
void make_permutation(int pre, int a[], int pos) {//读入一个数字,然后返回下一变化的数组
int i = 8;
while (pre) {
a[i--] = pre % 10;
pre /= 10;
}
if (pos == 1) {
int temp = a[0];
a[0] = a[1];
a[1] = a[4];
a[4] = a[3];
a[3] = temp;
return;
} else if (pos == 2) {
int temp = a[1];
a[1] = a[2];
a[2] = a[5];
a[5] = a[4];
a[4] = temp;
return;
} else if (pos == 3) {
int temp = a[3];
a[3] = a[4];
a[4] = a[7];
a[7] = a[6];
a[6] = temp;
return;
} else {
int temp = a[4];
a[4] = a[5];
a[5] = a[8];
a[8] = a[7];
a[7] = temp;
return;
}
}
int cantor(int a[]) {//康托
int pos = 0, count, i, j;
for (i = 0; i < 8; i++) {
count = 0;
for (j = i + 1; j < 9; j++) {
if (a[i] > a[j])
count++;
}
pos += count * fac[i];
}
return pos;
}
void bfs() {
queue<int> Q;
Q.push(123456789);
int step = 0;
int i, next[9];
int pos;
int now_size;
while (!Q.empty()) {
step++;//每次更新都是要走多一步的
now_size = Q.size();//记录当前的size,然后走完它(又会生成新的size)
while (now_size--) {
for (i = 1; i <= 4; i++) {//遍历四种转化
make_permutation(Q.front(), next, i);
pos = cantor(next);//通过康托获取位置
if (ans[pos] == 0) {//如果为0就是没有用过
ans[pos] = step;
Q.push(make_num(next));
}
}
Q.pop();//队首已经用过了
}
}
ans[0] = 0;
}
int main() {
bfs();
int sum[20];
while(~scanf("%d", &sum[0])) {
for (int i = 1; i <= 8; i++) {
scanf("%d", &sum[i]);
}
printf("%d\n", ans[cantor(sum)]);
}
return 0;
} 标签:sicily
原文地址:http://blog.csdn.net/u012925008/article/details/44739223