1 条题解
-
1
原文链接(也是我写的):【BFS】魔板(c++基础算法)_静渊隐者的博客-CSDN博客
做题
题意 很显然,这道题是让我们求12345678经过三种变化,到目标状态 的步数与变化操作。
①算法原理
这题与【BFS】八数码问题极其相似,我就在讲论两者间的区别中,来把这题讲给你。
②算法实现
Ⅰ三种基本操作
相对于八数码的空格上下左右操作,这题有三种不同的操作。
“A”:交换上下两行; “B”:将最右边的一列插入最左边; “C”:魔板中央四格作顺时针旋转。 下面是对基本状态进行操作的示范: A: 8 7 6 5 1 2 3 4 B: 4 1 2 3 5 8 7 6 C: 1 7 2 4 8 6 3 5
看到很多人都是用二维数组来搞,但我觉得没有必要。我直接在main函数中,利用switch()语句来进行。
“A”功能:循环j从1-4,交换a[j] 与a[9-j]。
“B”功能:循环j从1-3,交换a[j],a[4],和a[9-j],a[5].(不断对第j列[j会不断加1]和最后一列交换,最终达成目的)
“C”功能,直接换来换去。
{ case 1: for(int i=1;i<=4;i++) { swap(ne.a[i],ne.a[9-i]); } break; case 2: for(int i=1;i<=3;i++) { swap(ne.a[i],ne.a[4]); swap(ne.a[9-i],ne.a[5]); } break; case 3: swap(ne.a[3],ne.a[6]); swap(ne.a[7],ne.a[3]); swap(ne.a[3],ne.a[2]); }
Ⅱ操作序列
我将每钟情况都赋予一个序列。当此情况可行(之前没出现过),先将其上一步序列赋值到它身上,在增加此次操作的序列。
for(int k=1;k<=q.front().ans;k++) ```ne.bz[k]=q.front().bz[k]; ne.bz[ne.ans]=i;
Ⅲ输出 先将操作次数输出,再对序列操作,然后输出。
对序列的操作:原有基础上,强制转换为字符,加上‘A’,减一(因为序列数为1时应输出A,而不建议会变为B,因此要减一)
{ printf("%d\n",q.back().ans); for(int k=1;k<=q.back().ans;k++) printf("%c",q.back().bz[k]+'A'-1); exit(0); }
Ⅳ一个特殊情况
当目标状态与初始状态一样时,会无法进入我的输出语句。因此要在结尾输出一个0(因为当出现上述情况时,无需操作即可达到目标状态)
四.AC代码
不写注释啦!
using namespace std; struct node{ int kt,ans,bz[1005]; int a[10]; }st,ed; bool b[50000]; queueq; long kt(node t) { long long s=1; for(int i=1;i<=8;i++) { int index=1,f=1,count=0; for(int j=i+1;j<=8;j++) { if(t.a[i]>t.a[j]) count++; f*=index++; } s=s+f*count; } return s; } int main() { for(int i=1;i<=8;i++) st.a[i]=i; st.kt=kt(st); b[st.kt]=1; for(int i=1;i<=8;i++) scanf("%d",&ed.a[i]); ed.kt=kt(ed); q.push(st); while(!q.empty()) { for(int i=1;i<=3;i++) { node ne=q.front(); switch(i) { case 1: for(int i=1;i<=4;i++) { swap(ne.a[i],ne.a[9-i]); } break; case 2: for(int i=1;i<=3;i++) { swap(ne.a[i],ne.a[4]); swap(ne.a[9-i],ne.a[5]); } break; case 3: swap(ne.a[3],ne.a[6]); swap(ne.a[7],ne.a[3]); swap(ne.a[3],ne.a[2]); } ne.ans++; ne.kt=kt(ne); if(!b[ne.kt]) { for(int k=1;k<=q.front().ans;k++) ne.bz[k]=q.front().bz[k]; ne.bz[ne.ans]=i; b[ne.kt]=1; q.push(ne); if(ne.kt==ed.kt) { printf("%d\n",q.back().ans); for(int k=1;k<=q.back().ans;k++) printf("%c",q.back().bz[k]+'A'-1); exit(0); } } } q.pop(); } printf("0"); }
最后
我是在网课期间摸鱼写作的,很辛苦。给个红心不过分吧。。。
- 1
信息
- ID
- 1331
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 3
- 已通过
- 2
- 上传者