历届试题 九宫重排 蓝桥杯
来源:互联网 发布:淘宝上的跳蛋干净吗 编辑:程序博客网 时间:2024/06/09 14:49
问题描述
如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。
我们把第一个图的局面记为:12345678.
把第二个图的局面记为:123.46758
显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。
我们把第一个图的局面记为:12345678.
把第二个图的局面记为:123.46758
显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。
输入格式
输入第一行包含九宫的初态,第二行包含九宫的终态。
输出格式
输出最少的步数,如果不存在方案,则输出-1。
样例输入
12345678.
123.46758
123.46758
样例输出
3
样例输入
13524678.
46758123.
46758123.
样例输出
22
广搜
队列,hash验重
#include<cstdio>#include<cstring>const int state_maxsize=400010;const int dx[]={-1,1,0,0};const int dy[]={0,0,-1,1};typedef int state[9];state q[state_maxsize],goal;int dist[state_maxsize]={0};const int hash_size=10000000;int head[hash_size]={0},next[state_maxsize];int hash(state &x){int sum=0;for(int i=0;i<9;i++) sum=sum*10+x[i];return sum%hash_size;}int try_to_sert(int x){int h=hash(q[x]);int u=head[h];while(u){ while(memcmp(q[u],q[x],sizeof(q[x]))==0){ return 0; } u=next[u];}next[x]=u;head[h]=x;return 1;}int bfs(){int front=1;int rear=2;while(front<rear){ state&s=q[front]; if(memcmp(goal,s,sizeof(s))==0)return front; int z=0; while(s[z]!=0)z++; int x=z/3; int y=z%3; for(int i=0;i<4;i++){ int newx=x+dx[i]; int newy=y+dy[i]; int newz=newx*3+newy; if(newx>=0&&newx<3&&newy>=0&&newy<3){ state&t=q[rear]; memcpy(t,s,sizeof(s)); t[newz]=s[z]; t[z]=s[newz]; dist[rear]=dist[front]+1; if(try_to_sert(rear))rear++; } } front++;}return 0;}int main(){char c;for(int i=0;i<9;i++){ if((c=getchar())!='.') q[1][i]=c-'0'; else q[1][i]=0;}getchar();for(int i=0;i<9;i++){ if((c=getchar())!='.') goal[i]=c-'0'; else goal[i]=0;}if(int y=bfs()) printf("%d\n",dist[y]);else printf("-1\n");}
与单向广搜的区别,在于把起点终点依次放入队列,然后你一层,我一层地遍历;验重的时候,分辨是于哪个出发点出发的路径重叠。
#include<cstdio>#include<cstring>const int state_maxsize=400010;const int dx[]={-1,1,0,0};const int dy[]={0,0,-1,1};typedef int state[9];state q[state_maxsize];int dist[state_maxsize]={0};int root[state_maxsize]={0};const int hash_size=10000000;int head[hash_size]={0},next[state_maxsize];int hash(state &x){int sum=0;for(int i=0;i<9;i++) sum=sum*10+x[i];return sum%hash_size;}int try_to_sert(int x){int h=hash(q[x]);int u=head[h];while(u){ while(memcmp(q[u],q[x],sizeof(q[x]))==0){ if(root[u]==root[x]) return 0; else return u; } u=next[u];}next[x]=u;head[h]=x;return 1;}int bfs(){root[1]=1;root[2]=2;int front=1;int rear=3;while(front<rear){ state&s=q[front]; int z=0; while(s[z]!=0)z++; int x=z/3; int y=z%3; for(int i=0;i<4;i++){ int newx=x+dx[i]; int newy=y+dy[i]; int newz=newx*3+newy; if(newx>=0&&newx<3&&newy>=0&&newy<3){ state&t=q[rear]; memcpy(t,s,sizeof(s)); t[newz]=s[z]; t[z]=s[newz]; root[rear]=root[front]; dist[rear]=dist[front]+1; switch(int u=try_to_sert(rear)){ case 0:break; case 1:rear++;break; default:return dist[u]+dist[rear]; } } } front++;}return 0;}int main(){char c;for(int i=0;i<9;i++){ if((c=getchar())!='.') q[1][i]=c-'0'; else q[1][i]=0;}getchar();for(int i=0;i<9;i++){ if((c=getchar())!='.') q[2][i]=c-'0'; else q[2][i]=0;}if(int y=bfs()) printf("%d\n",y);else printf("-1\n");}
蓝桥oj上单向花了156ms,双向花了15ms。
0 0
- 蓝桥杯 历届试题-九宫重排
- 蓝桥杯 历届试题 九宫重排
- 蓝桥杯 历届试题 九宫重排
- 历届试题 九宫重排 蓝桥杯
- 蓝桥杯【历届试题】九宫重排
- 历届试题 九宫重排
- 历届试题 九宫重排
- 蓝桥杯 历届试题 九宫重排 BFS Java
- 蓝桥杯-历届试题-九宫重排-BFS+剪枝
- 蓝桥网 历届试题 九宫重排
- 蓝桥杯, 历届试题 九宫重排 (八数码)
- 蓝桥杯 历届试题 九宫重排(双向搜索优化)
- 蓝桥杯 历届试题 九宫重排 (广搜)
- 蓝桥杯历届试题——九宫重排(bfs)
- 蓝桥杯历届试题——九宫重排(启发式搜索)
- 历届试题 九宫重排 (搜索+哈希)
- 历届试题 九宫重排 (bfs 康托判重)
- 蓝桥杯 历届试题 九宫重排 经典八数码问题 A*算法+康托展开
- [多线程] Web 项目中,少有涉及到的一次多线程编程的经验
- Java 实现 Dijsktra 算法
- 树莓派安装Lakka打造经典小霸王游戏机
- C++类中常量定义
- SpringMVC——/和/*的区别以及原理分析
- 历届试题 九宫重排 蓝桥杯
- HTML&CSS设计与构建网站(一)
- 校园宽带客户端认证程序无法继续初始化绑定通信接口网络地址失败_解决办法
- (转)SpringMVC:提交数据遭遇基础类型和日期类型报400错误解决方法
- 简述web功能
- 关于指数记数法在%la,%le,%lf下的输出~
- 分页处理
- 我的心得五:一个没有方法论的人生,该有多么混乱
- POJ