HDU - 1043 Eight(启发式搜索---九宫格)---map容器是关键

题目链接:https://cn.vjudge.net/contest/311091#problem/C
给出一个字符串,表示九宫格此时的状态,问怎么走,能走到九宫格的目标状态(12345678x),如果能走,输出路径(l:往左走,r:往右走,u:往上走,d:往下走),不能走输出unsolvable。

:拼图的解法,可以用搜索的状态迁移来解决。迁移是整个九宫格的迁移,不是改变哪两个点,哪两个点迁移,改变一次,九宫格就不是原来的九宫格,把整个九宫格迁移。
解析
总体思路:输入的是一行字符串,目标状态是123456780(把x用0表示)。从目标状态出发,变成不是目标状态,记录走的轨迹。对应输入的字符串,找相应的轨迹,倒着输出路径即可。
细节1:每次的状态都是一个长度为9的数字。定义mapu,将能到达的状态映射为1
细节2:定义mapv,将每个状态的路径,存到字符串中,每次的状态映射为字符串
细节3
定义结构体

struct node
{
    string t;//存路径
    int s[3][3];
    int x,y;
};

s数组为每次九宫格的状态,(x,y)表示x的坐标。

代码:

#include
#include
#include
#include
#include
#include
#include
using namespace std;
int dis[4][2]= {0,1,1,0,0,-1,-1,0};
mapu;
mapv;
struct node{
    string t;//存路径
    int s[3][3];//目标状态
    int x,y;
};
void bfs(){
    queueQ;
    node now,next;
    int sum=1;
    for(int i=0; i<3; i++)
        for(int j=0; j<3; j++)
            now.s[i][j]=sum++;
    now.s[2][2]=0;
    now.x=2,now.y=2;
    u[123456780]=1;
    Q.push(now);
    while(!Q.empty()){
        now=Q.front();
        Q.pop();
        for(int i=0; i<4; i++){
            int tx=now.x+dis[i][0],ty=now.y+dis[i][1];
            if(tx<0||tx>=3||ty<0||ty>=3)continue;
            for(int j=0; j<3; j++)//更新9宫格的各个点的值
                for(int k=0; k<3; k++)
                    next.s[j][k]=now.s[j][k];
            swap(next.s[now.x][now.y],next.s[tx][ty]);
            int sum=1;
            for(int j=0; j<3; j++)
                for(int k=0; k<3; k++)
                    sum=10*sum+next.s[j][k];
            if(u[sum])continue;
            u[sum]=1;
            next.x=tx,next.y=ty;
            if(i==0)next.t=now.t+'l';
            if(i==1)next.t=now.t+'u';
            if(i==2)next.t=now.t+'r';
            if(i==3)next.t=now.t+'d';
            Q.push(next);
            v[sum]=next.t;
        }
    }
}
int main(){
    char str[50];
    bfs();//遍历不是目标状态的各种情况
    while(gets(str)){
        int sum=1,len=strlen(str);
        for(int i=0; i='1'&&str[i]<='9')
                sum=10*sum+(str[i]-'0');
            if(str[i]=='x')
                sum=10*sum;
        }
        if(!u[sum]){
            printf("unsolvable\n");//状态没有出现过
            continue;
        }
        string s=v[sum];
        len=s.size();
        for(int i=len-1; i>=0; i--)
            printf("%c",s[i]);
        printf("\n");
    }
    return 0;
}

HDU - 1043 Eight(启发式搜索---九宫格)---map容器是关键_第1张图片

你可能感兴趣的:(搜索,容器)