C++ 八数码问题宽搜

C++ 八数码问题宽搜

题目描述

照片中表示的是从城市A到城市H的交通图。从图中可以看出,城市A到H要经过若干个城市。现在要找出一条经过城市最少的路线。

具体过程如下:

(1)讲城市A入队,队首为0,队尾为1

(2)将队首所指向的城市,所有可以直通的城市入队(如果这个城市在队列中出现过,就不入队,可以用一个布尔数组s[i]来判断),将入队城市的前趋城市保存在b[i]中,然后将队首加1,得到新的队首城市。重复以上步骤,知道搜到城市H时,搜索结束。利用b[i]可倒推出最少城市路线。

样例输入

(none)

样例输出

H--F--A

AC代码


#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
int ju[9][9] = {{0,0,0,0,0,0,0,0,0},
                {0,1,0,0,0,1,0,1,1},
                {0,0,1,1,1,1,0,1,1},
                {0,0,1,1,0,0,1,1,1},
                {0,0,1,0,1,1,1,0,1},
                {0,1,1,0,1,1,1,0,0},
                {0,0,0,1,1,1,1,1,0},
                {0,1,1,1,0,0,1,1,0},
                {0,1,1,1,1,0,0,0,1}};//根据图来生成矩阵 
int a[101],b[101];//a是经过的城市    b是记录前趋城市      
bool s[9];//true为不可走 false为可走 为了避免重复
void out(int d)//作用是把数组按char输出
{
    cout << char(a[d] + 'A' - 1);//将数字转换成字母   (一个数字 +'A'-1 (+64) 才是char)
    while (b[d])//重复输出,直到没有前趋城市为止(达到起点) 
    {
        d = b[d];
        cout << "--" << char(a[d] + 'A' - 1);//后面的数字用"--"隔开
    }
    cout << endl;
}
void doit()
{
    int head,tail,i;
    head = 0;tail = 1;//head出队下标      tail入队下标 
    a[1] = 1;//a[]是现在经过的城市 把起点的城市放在队列的第一个数 
    b[1] = 0;//b[]保存入队城市的前趋城市 因为A没有前趋 所以为0 
    s[1] = 1;//s[]判断是否能走或是否被选择过 0是能或者没被选择 1是不能或者已被选择 
///////////////////////////Start to BFS/////////////////////////////////////
    do//重复执行直到出队下标 <= 入队下标 保证不越界  (head < tail)
    {
        head ++;//head是出队下标
        for (i = 1;i <= 8;i ++)//每一行遍历8列的矩阵元素 
        {
            if (ju[a[head]][i] == 0 && s[i] == 0)//如果这个城市可以走,并且以前没有入队,那就入队
            {//s[]控制入队元素是否重复 
                tail ++;//入队下标 + 1
                a[tail] = i;//入队都入队
                b[tail] = head;
                s[i] = 1;//把当前城市标为已经选择过 
				if (i == 8)//因为目标在第8列 
                {
                    out(tail);//输出函数 递归输出目标城市的前趋城市(即为起点到目标城市的最短路线) 
                    head = tail;//
                    break;//直接退出
                }
            }
        }
    }while (head < tail);
}
int main()
{
//	freopen("out.txt","w",stdout);
    memset(s,false,sizeof(s));//把s下标里的元素全部初始化为False
    doit();//调用
    return 0;//
}

posted @ 2019-07-26 16:18  牛大了的牛大  阅读(724)  评论(0编辑  收藏  举报