蓝桥杯—第八届—A组—第二题—跳蚱蜢 {C语言}=====【可调试】
如图 p1.png 所示:
有9只盘子,排成1个圆圈。
其中8只盘子内装着8只蚱蜢,有一个是空盘。
我们把这些蚱蜢顺时针编号为 1~8
每只蚱蜢都可以跳到相邻的空盘中,
也可以再用点力,越过一个相邻的蚱蜢跳到空盘中。
请你计算一下,如果要使得蚱蜢们的队形改为按照逆时针排列,
并且保持空盘的位置不变(也就是1-8换位,2-7换位,...),至少要经过多少次跳跃?
注意:要求提交的是一个整数,请不要填写任何多余内容或说明文字。
这个题的思路是bfs,我本来用的dfs怎么都不对,
而且我写的这个也不是正确答案,因为6以下的数都行,如果超过6位数就不行了,应该是内存过大
目前还不知道怎么解决: 见谅
语言是C语言,
圆圈用的 循环队列模拟,那个求0的位置和分解的函数可以只用一个就行,写麻烦了,每一个函数后边都谢了注释功能是什么,英语不好请见谅,使用的拼音,希望能帮助你们一点点
这个题是求的最短路径,我把每次怎么执行的步骤存到了,ma数组中,这样就可以用一个小范围的数据调试,清除每一步的步骤
这个题和八数码有点相似,都是bfs,我学的还不够好,大神看到请指点指点
代码有点多,希望仔细看看,是C语言,写的还行,这个题困扰了我两三天
因为我做题一直是bfs,还好把我稍微看看了数据结构
虽然不是严蔚敏,严蔚敏这本书挺好的,里面有算法
下面是代码
#include<stdio.h>
#include<string.h>
#define N 6//位数
#define M 54321//需要转动的状态
#define MM 12345 //初始状态
int a[9] = {0,1,2,3,4,5,6,7,8}; //这个是总共有八个蚱蜢,
//但是我做的超过了留个就不行了,应该是超时了,不知道怎么弄
int max[5000000] ={0};//判断重复
int ma[500][2] = {0};//存储路径
int way[500]; //变化后的状态
int F = 0,P = 0;//第一个记录max的位置,第二个记录是否有重复
int fenjie(int k)//把每一位 N-1 位数 分解在a数组中,方便交换
{
int i,j;
for(i = N - 1; i >= 0;i--)
{
a[i] = k % 10;
k /= 10;
if(a[i] == 0)
j = i;
}
return j;
}
int weizhi0(int n)//求0的位置
{
int k = n;
int i = N;
while(k)
{
i--;
if(k % 10 == 0)
return i;
k/=10;
}
}
void swap(int i,int j)//交换
{
int t = a[i];
a[i] = a[j];
a[j] = t;
}
int sum()//求和
{
int i,s = 0,l = 1;
for(i = N-1; i >= 0; i--)
{
s += l*a[i];
l *= 10;
}
return s;
}
int f(int n)//n:总共执行了多少次
{
int k;
int i = fenjie(max[n]);
int one = i - 1,two = i - 2;
int one1 = (i+1)%N,two1 = (i+2)%N;
if(P == 0)//没有相等的
{
if(one < 0)
one = N + one;
if(two < 0)
two = N + two;
swap(i,two1);
k = sum();
max[++F] = k;
if(k == M){
P = 1;
}
swap(i,two1);
swap(i,one1);
k = sum();
max[++F] = k;
if(k == M){
P = 1;
}
swap(i,one1);
swap(i,one);
k = sum();
max[++F] = k;
if(k == M){
P = 1;
}
swap(i,one);
swap(i,two);
k = sum();
max[++F] = k;
if(k == M){
P = 1;
}
swap(i,two);
f(n+1);//递归
}
}
int shuchubuzhou(int i)// 给way数组赋值步骤
{
int j,k,s = 0;
while(i)
{
j = weizhi0(way[i]);
k = weizhi0(way[i-1]);
ma[s][0] = k;
ma[s][1] = j;
s++;
i--;
}
ma[s][0] = 0;
ma[s][1] = k;
}
int printff(int s)//输出步骤
{
int j,i = 1,x = 1;
while(i++<N)
{
x *= 10;
}
way[0] = M;
printf("初始\t 0%d 下标\n\n",MM);
for(j = 1,i = s-1; i >= 0; i--,j++)
{
printf("第%d步:",j);
if(way[i] / x == 0)printf(" 0%d ",way[i]);
else printf(" %d ",way[i]);
printf("%d->%d\n",ma[j][1],ma[j][0]);
}
printf("结束\n");
printf("\n总共%d步\n",s);
}
int wayfuzhi()//给way数组赋值 ,每次变换后的数值
{
int s = 0;
while(F)
{
s++;
F = (F - 1)/4;
way[s] = max[F];
}
return s;
}
int main()
{
int s;
max[0] = MM;//给第一个位置赋值
f(0);//调用函数
//printf("%d\n",F);//输出在bfs中的结束表格
s = wayfuzhi();//给way进行赋值
shuchubuzhou(s+1);//把步骤赋值到way数组中
printff(s);//输出步骤
}