路径寻找问题

来源:互联网 发布:scratch创意编程 pdf 编辑:程序博客网 时间:2024/06/01 09:09

     路径寻找问题可以归结为隐式图的遍历,他的任务是找到一条路径从初始状态到终止状态的最优路径,而不是像回溯法那样找到一个符合某些要求的解

经典的八数码问题:编号为1 ~ 8 的8个正方形滑块被摆成3行3列(有一个格子为空),每次可以把空格和相邻的四个滑块互换,给定初始和目标局面(0表示空格),

你的任务是计算从初始到目标位置最少移动的步数,如果无法达到则输出-1;

输入: 2 6 4 1 3 7 0 5 8

             8 1 5 7 3 6 4 04

输出: 31


代码:

#include<iostream>#include<cstdio>#include<cstring>#include<typeinfo>#include<set>using namespace std;typedef int State[9]; // 定义状态const int maxstate = 1000000;State st[maxstate], goal;int dist[maxstate];const int dx[] = {-1, 1, 0, 0};const int dy[] = {0, 0, -1, 1};/*set<int> vis;void init_lookup_table(){    vis.clear();}int try_to_insert(int s){    int v = 0;    for(int i = 0; i < 9; i++)        v = v * 10 + st[s][i];    if(vis.count(v)) return 0;    vis.insert(v);    return 1;}*/const int hashsize = 1000003;int head[hashsize], next[maxstate];void init_lookup_table(){    memset(head, 0, sizeof(head));}int hash(State & s){    int v = 0;    for(int i = 0; i < 9; i++)        v = v * 10 + s[i];    return v % hashsize;}int try_to_insert(int s){    int h = hash(st[s]);    int u = head[h];    while(u)    {        if(memcmp(st[u], st[s], sizeof(st[s])) == 0)            return 0;        u = next[u];    }    next[s] = head[h];    head[h] = s;    return 1;}//把一个一个的状态看作结点,int bfs(){    init_lookup_table();    int front = 1, rear = 2;    while(front < rear)    {        State& s = st[front];        if(memcmp(goal, s, sizeof(s)) == 0) return front; //找到目标        int z;        for(z = 0; z < 9; z++)        {            if(!s[z]) break;  //  find "space"        }        int x = z / 3, y = z % 3; // move "space"        for(int d = 0; d < 4; d++)        {            int newx = x + dx[d];            int newy = y + dy[d];            int newz = newx*3 + newy;            if(newx >= 0 && newx < 3 && newy >= 0 && newy < 3)            {                State & t = st[rear];                memcpy(&t, &s, sizeof(s));                t[newz] = s[z];                t[z] = s[newz];                dist[rear] = dist[front] + 1;                if(try_to_insert(rear)) rear++;            }        }        front++;    }    return 0;}int main(){    for(int i = 0; i < 9; i++)        scanf("%d", &st[1][i]);    for(int i = 0; i < 9; i++)        scanf("%d", &goal[i]);    int ans = bfs();    if(ans > 0) printf("%d\n", dist[ans]);    else printf("-1\n");    return 0;}