您的位置:首页 > 其它

蓝桥杯 历届试题 九宫重排 (广搜)

2016-04-18 21:54 337 查看
历届试题 九宫重排

时间限制:1.0s 内存限制:256.0MB

问题描述

  如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。





  我们把第一个图的局面记为:12345678.

  把第二个图的局面记为:123.46758

  显然是按从上到下,从左到右的顺序记录数字,空格记为句点。

  本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。

输入格式

  输入第一行包含九宫的初态,第二行包含九宫的终态。

输出格式

  输出最少的步数,如果不存在方案,则输出-1。

样例输入

12345678.

123.46758

样例输出

3

样例输入

13524678.

46758123.

样例输出

22

主要是标记剪枝,我用的set,不过听学长说可以用康托展开,可是康托展开好难。。

写得挺蠢的也过了,蓝桥数据应该挺水的吧。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <set>
using namespace std;
char map1[5][5], map2[5][5];
int b1x, b1y;
struct node {
int x, y, step;
char m[5][5];
};
int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
set<string> s;
int bfs() {
queue<node> q;
node now, next;
now.x = b1x, now.y = b1y, now.step = 0;
memcpy(now.m, map1, sizeof(map1));
char tstr[10];
int i, j, k = 0;
for(i = 1; i <= 3; i++) {
for(j = 1; j <= 3; j++) {
tstr[k++] = map1[i][j];
}
}
tstr[k] = 0;
string str(tstr);  //字符数组转string
s.insert(str);
q.push(now);
while(!q.empty()) {
now = q.front();
q.pop();
int flag = 0;
for(i = 1; i <= 3; i++) {  //退出条件
for(j = 1; j <= 3; j++) {
if(now.m[i][j] != map2[i][j]) {
flag = 1;
break;
}
}
if(flag) break;
}
if(i == 4) return now.step;
for(i = 0; i < 4; i++) {
next.x = now.x + dir[i][0];
next.y = now.y + dir[i][1];
next.step = now.step + 1;
if(next.x < 1 || next.x > 3 || next.y < 1 || next.y > 3) continue;
memcpy(next.m, now.m, sizeof(now.m));
next.m[now.x][now.y] = next.m[next.x][next.y];
next.m[next.x][next.y] = '.';
int i, j, k = 0;
for(i = 1; i <= 3; i++) {
for(j = 1; j <= 3; j++) {
tstr[k++] = next.m[i][j];
}
}
string str1(tstr);
if(s.count(str1) == 1) continue;
else s.insert(str1);
q.push(next);
}
}
return -1;
}
int main() {
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
int i, j;
for(i = 1; i <= 3; i++) {
for(j = 1; j <= 3; j++) {
scanf("%c", &map1[i][j]);
if(map1[i][j] == '.') b1x = i, b1y = j;
}
}
getchar();
for(i = 1; i <= 3; i++) {
for(j = 1; j <= 3; j++) {
scanf("%c", &map2[i][j]);
}
}
getchar();
cout << bfs() << endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: