zoukankan      html  css  js  c++  java
  • 八数码

    Description

    The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've seen it. It is constructed with 15 sliding tiles, each with a number from 1 to 15 on it, and all packed into a 4 by 4 frame with one tile missing. Let's call the missing tile 'x'; the object of the puzzle is to arrange the tiles so that they are ordered as: 
     1  2  3  4 
    5 6 7 8
    9 10 11 12
    13 14 15 x

    where the only legal operation is to exchange 'x' with one of the tiles with which it shares an edge. As an example, the following sequence of moves solves a slightly scrambled puzzle: 
     1  2  3  4    1  2  3  4    1  2  3  4    1  2  3  4 
    5 6 7 8 5 6 7 8 5 6 7 8 5 6 7 8
    9 x 10 12 9 10 x 12 9 10 11 12 9 10 11 12
    13 14 11 15 13 14 11 15 13 14 x 15 13 14 15 x
    r-> d-> r->

    The letters in the previous row indicate which neighbor of the 'x' tile is swapped with the 'x' tile at each step; legal values are 'r','l','u' and 'd', for right, left, up, and down, respectively. 

    Not all puzzles can be solved; in 1870, a man named Sam Loyd was famous for distributing an unsolvable version of the puzzle, and 
    frustrating many people. In fact, all you have to do to make a regular puzzle into an unsolvable one is to swap two tiles (not counting the missing 'x' tile, of course). 

    In this problem, you will write a program for solving the less well-known 8-puzzle, composed of tiles on a three by three 
    arrangement. 

    Input

    You will receive a description of a configuration of the 8 puzzle. The description is just a list of the tiles in their initial positions, with the rows listed from top to bottom, and the tiles listed from left to right within a row, where the tiles are represented by numbers 1 to 8, plus 'x'. For example, this puzzle 
     1  2  3 
    x 4 6
    7 5 8

    is described by this list: 

    1 2 3 x 4 6 7 5 8

    Output

    You will print to standard output either the word ``unsolvable'', if the puzzle has no solution, or a string consisting entirely of the letters 'r', 'l', 'u' and 'd' that describes a series of moves that produce a solution. The string should include no spaces and start at the beginning of the line.

    Sample Input

     2  3  4  1  5  x  7  6  8 

    Sample Output

    ullddrurdllurdruldr

    经典的八数码问题,不过这道题的难点主要在于时间限制,如果时间开放为十秒,估计问题也就没那么复杂了,直接用stl中的map去重及标记。

    可是时间限制为一秒,这就说明无法采用stl,只能用hash+BFS

    开始的时候用hash+BFS 做了一个:

    #include"iostream"
    #include"cstring"
    #include"queue"
    #include"stack"
    using namespace std;
    
    const int maxn=370000;
    
    int book[maxn];
    
    struct  node
    {
        int status[9];   //记录当前状态
        int log;         //记录x的位置
        int hashd;         //记录当前状态哈希值
        string path;     //记录路径
    };
    
    int goal[]={1,2,3,4,5,6,7,8,0};
    int aim;
    
    int mov1[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
    string mov2="udlr";
    
    string ans;
    
    int HASH[10]={1,1,2,6,24,120,720,5040,40320,362880};
    
    int cantor(int a[])
    {
        int answer=0;
        int number=0;
        for(int i=0;i<9;i++)
        {
            number=0;
            for(int j=i+1;j<9;j++)
            if(a[i]>a[j]) number++;
            answer+=number*HASH[8-i];
        }
       return answer+1;
    }
    
    
    int BFS(struct node c)
    {
    queue<struct node> que;
    
    que.push(c);
    
    book[c.hashd]=1;
    
    while(!que.empty())
    {
    struct node cur,nex;
    cur=que.front();
    if(cur.hashd==aim)
    {
        ans=cur.path;
     //   for(int kk=0;kk<9;kk++) cout<<cur.status[kk]<<' ';
        return 1;
    }
    que.pop();
    int x=cur.log/3;
    int y=cur.log%3;
    for(int k=0;k<4;k++)
    {
     int tx=x+mov1[k][0];
     int ty=y+mov1[k][1];
    
     if(tx<0||tx>2||ty<0||ty>2)
            continue;
    nex=cur;
    nex.log=tx*3+ty;
    nex.status[cur.log]=nex.status[nex.log];
    nex.status[nex.log]=0;
    nex.hashd=cantor(nex.status);
    if(book[nex.hashd]==0)
    {
        book[nex.hashd]=1;
        nex.path+=mov2[k];
        que.push(nex);
    }
    }
    
    }
        return 0;
    }
    
    
    
    
    
    
    
    
    int main()
    {
        struct node ncur;
        char ch;
        aim=cantor(goal);
       // cout<<aim<<endl;
        cin>>ch;
        memset(book,0,sizeof(book));
        if(ch=='x')
        {
            ncur.status[0]=0;
            ncur.log=0;
        }
        else
        {
            ncur.status[0]=ch-'0';
        }
        for(int i=1;i<=8;i++)
        {
            cin>>ch;
            if(ch=='x')
            {
                ncur.status[i]=0;
                ncur.log=i;
            }
            else
            {
                ncur.status[i]=ch-'0';
            }
    
        }
        ncur.hashd=cantor(ncur.status);
        if(BFS(ncur)) cout<<ans<<endl;
        else cout<<"unsolvable"<<endl;
    
    
    
    }
    结果超时,后来将每次都记录字符串改为记录单个的字符,过了

    #include"iostream"
    #include"cstring"
    #include"queue"
    #include"cstdio"
    #include"stack"
    using namespace std;
    
    const int maxn=370000;
    
    struct note
    {
        int flag;
        int f;
        char path;
    };
    
    
    
    struct note book[maxn];
    
    struct  node
    {
        int status[9];   //记录当前状态
        int log;         //记录x的位置
        int hashd;         //记录当前状态哈希值
    };
    
    int goal[]={1,2,3,4,5,6,7,8,0};
    int aim;
    
    int mov1[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
    string mov2="udlr";
    
    string ans;
    
    int HASH[10]={1,1,2,6,24,120,720,5040,40320,362880};
    
    int cantor(int a[])
    {
        int answer=0;
        int number=0;
        for(int i=0;i<9;i++)
        {
            number=0;
            for(int j=i+1;j<9;j++)
            if(a[i]>a[j]) number++;
            answer+=number*HASH[8-i];
        }
       return answer+1;
    }
    
    
    int BFS(struct node c)
    {
    queue<struct node> que;
    
    que.push(c);
    
    book[c.hashd].f=0;
    
    book[c.hashd].flag=1;
    
    book[c.hashd].path='k';
    
    while(!que.empty())
    {
    struct node cur,nex;
    cur=que.front();
    if(cur.hashd==aim)
    {
      //     ans=cur.path;
     //   for(int kk=0;kk<9;kk++) cout<<cur.status[kk]<<' ';
        return 1;
    }
    que.pop();
    int x=cur.log/3;
    int y=cur.log%3;
    for(int k=0;k<4;k++)
    {
     int tx=x+mov1[k][0];
     int ty=y+mov1[k][1];
    
     if(tx<0||tx>2||ty<0||ty>2)
            continue;
    nex=cur;
    nex.log=tx*3+ty;
    nex.status[cur.log]=nex.status[nex.log];
    nex.status[nex.log]=0;
    nex.hashd=cantor(nex.status);
    if(book[nex.hashd].flag==0)
    {
        book[nex.hashd].flag=1;
        book[nex.hashd].f=cur.hashd;
      //  nex.path+=mov2[k];
        book[nex.hashd].path=mov2[k];
        que.push(nex);
    }
    }
    
    }
        return 0;
    }
    
    
    
    
    
    
    
    
    int main()
    {
    
        char ch;
        aim=cantor(goal);
       // cout<<aim<<endl;
        while(cin>>ch)
        {
        struct node ncur;
        memset(book,0,sizeof(book));
        if(ch=='x')
        {
            ncur.status[0]=0;
            ncur.log=0;
        }
        else
        {
            ncur.status[0]=ch-'0';
        }
        for(int i=1;i<=8;i++)
        {
            cin>>ch;
            if(ch=='x')
            {
                ncur.status[i]=0;
                ncur.log=i;
            }
            else
            {
                ncur.status[i]=ch-'0';
            }
    
        }
        ncur.hashd=cantor(ncur.status);
        if(BFS(ncur))
        {
            stack<char> st;
            int id=aim;
            while(book[id].f!=0)
            {
                st.push(book[id].path);
                id=book[id].f;
            }
            while(!st.empty())
            {
                cout<<st.top();
                st.pop();
            }
        }
        else cout<<"unsolvable"<<endl;
        }
      return 0;
    
    }
  • 相关阅读:
    fn project 试用之后的几个问题的解答
    fn project 扩展
    fn project 生产环境使用
    fn project 对象模型
    fn project AWS Lambda 格式 functions
    fn project 打包Function
    fn project Function files 说明
    fn project hot functions 说明
    fn project k8s 集成
    fn project 私有镜像发布
  • 原文地址:https://www.cnblogs.com/zsyacm666666/p/4670491.html
Copyright © 2011-2022 走看看