最近老师让用程序解决八数码问题,当时注意到可以从中抽取出来的简单模型——三数码,就是4个格子三个数,然后用C++写了一个求解可达不可达且可达的话求出最少步长的简单算法:
/* 三数码问题求解 */
/* 找出数据结构和算法 */
/* 结合测试生成的测试用例方法以及代码优化方法 */
/* 注释 */
/* 证明程序的正确性 写测试代码 */
/* 比较复杂的话,会用到记忆结点 */
#include<iostream>
using namespace std;
int main() {
int d[4] = {0}; //初态
int des[4] = {0}; //目标态
int flag[3] = {0},flag1[3] = {0},k,t,status;
int t1[3],t2[3]; //存储初态和目标态各大于0的数的位置
int b1,b2; //计算顺时针和逆时针的最小步数
cout<<"请输入三数码的值:"<<endl;
cin>>d[0]>>d[1]>>d[2]>>d[3];
cout<<"请输入目标值:"<<endl;
cin>>des[0]>>des[1]>>des[2]>>des[3];
/* 对初态和目标态做顺序统计 */
k = 0;
for(int i = 0;i < 4;i++){
if(d[i] != 0){
flag[k] = d[i]; //存储隐藏顺序
t1[k] = i;
++k;
}
}
k = 0;
t = 0;
for(int i = 0;i < 7;i++){
if(k == 0 && des[i%4] != 0 && des[i%4] == d[k]){
flag1[k] = des[i%4];
t2[k] = i % 4;
++t; //统计从这里开始遇到的des[i]不为0的总量
++k;
}
else if(k != 0 && des[i%4] != 0 && t < 3){
flag1[k] = des[i%4];
t2[k] = i % 4;
++t;
++k;
}
else if(t == 3){
break;
}
}
/* 判断是否可达 */
status = 0;
k = 0;
for(int i = 0;i < 4;i++){
if(flag[i] != flag1[i]){
cout<<"不可达!";
k = 1;
break;
}
}
if(k == 0){
cout<<"可达!";
status = 1;
}
/* 测试代码
for(int i=0;i<3;i++){
cout<<t1[i]<<" ";
}
cout<<endl;
for(int i=0;i<3;i++){
cout<<t2[i]<<" ";
}
cout<<endl; */
/* 计算从初态到终态最少的步数 */
k = 0;
if(status == 1){
/* 计算顺时针步数 */
b1 = 0;
for(int i=0;i<3;i++){
if(t1[i]<=t2[i]){
b1 = b1 + (t2[i] - t1[i]);
}
else{
b1 = b1 + (3-t1[i]) + (t2[i] + 1);
}
}
/* 计算逆时针步数 */
b2 = 0;
for(int i=0;i<3;i++){
if(t1[i]<=t2[i]){
b2 = b2 + t1[i] + 4 - t2[i];
}
else{
b2 = b2 + t1[i] - t2[i];
}
}
/* 比较顺时针最少步数和逆时针最少步数得出最少步数 */
if(b1 <= b2){
cout<<"最少步数为:"<<b1<<endl;
} else {
cout<<"最少步数为:"<<b2<<endl;
}
}
return 0;
}