您的位置:首页 > 其它

蓝桥杯历届试题 九宫重排(输入输出方式选择)

2018-03-23 10:59 405 查看
题目:如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。

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

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

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

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






4000
路:简单bfs。

注意点:开始我采用选择char*,代码太复杂,所以又选择了string,但在此基础上再优化才能得满分,也就是采用char*给string初始化。

另外:

将所有scanf换成cin,并且在头部加上:

cin.tie(0);ios::sync_with_stdio(false);

也能得满分,且用时更少。至于原理,我有空再补吧~



ac代码:

#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;

typedef long long ll;
const int N=1e4+5;

struct node{
string s;
int pos,num;
node(){}
node(string e,int p,int n):s(e),pos(p),num(n){}
};
map<string,bool> m;
queue<node> q;
int main(){
string s,e;
char t1[11],t2[11];
scanf("%s%s",t1,t2);
s=t1,e=t2;
int x,y;
for(int i=0;i<9;i++) if(s[i]=='.') x=i;
q.push(node(s,x,0));
m[s]=1;
while(!q.empty()){
node t=q.front();
q.pop();
if(t.s==e) return 0*printf("%d\n",t.num);
x=t.pos;
s=t.s;
y=t.num;
if(x%3!=2){
swap(s[x],s[x+1]);
if(m.find(s)==m.end()){
m[s]=1,q.push(node(s,x+1,y+1));
}
swap(s[x],s[x+1]);
}
if(x%3!=0){
swap(s[x],s[x-1]);
if(m.find(s)==m.end()){
m[s]=1,q.push(node(s,x-1,y+1));
}
swap(s[x],s[x-1]);
}
if(x<=5){
swap(s[x],s[x+3]);
if(m.find(s)==m.end()){
m[s]=1,q.push(node(s,x+3,y+1));
}
swap(s[x],s[x+3]);
}
if(x>=3){
swap(s[x],s[x-3]);
if(m.find(s)==m.end()){
m[s]=1,q.push(node(s,x-3,y+1));
}
swap(s[x],s[x-3]);
}
}
return 0*puts("-1");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: