zoukankan      html  css  js  c++  java
  • 2015 UESTC 搜索专题F题 Eight Puzzle 爆搜

    Eight Puzzle

    Time Limit: 20 Sec  Memory Limit: 256 MB

    题目连接

    http://acm.uestc.edu.cn/#/contest/show/61

    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. To simplify this problem, you should print the minimum steps only.



    Input

    There are multiple test cases.

    For each test case, 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.Otherwise, output an integer which equals the minimum steps.

    Sample Input

    1 2 x 4 5 3 7 8 6

    Sample Output

    2

    HINT

    Any violent algorithm may gain TLE. So a smart method is expected.

    The data used in this problem is unofficial data prepared by hzhua. So any mistake here does not imply mistake in the offcial judge data.

    题意

     八数码问题

    题解:

    爆搜题
    八数码:
    1.A*搜索,是否AC看脸
    2.双向BFS
    3.单次BFS预处理之后,O(1)回答

    代码:

    //qscqesze
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <set>
    #include <vector>
    #include <sstream>
    #include <queue>
    #include <typeinfo>
    #include <fstream>
    #include <map>
    #include <stack>
    typedef long long ll;
    using namespace std;
    //freopen("D.in","r",stdin);
    //freopen("D.out","w",stdout);
    #define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
    #define maxn 200001
    #define mod 10007
    #define eps 1e-9
    int Num;
    char CH[20];
    //const int inf=0x7fffffff;   //нчоч╢С
    const int inf=0x3f3f3f3f;
    /*
    
    inline void P(int x)
    {
        Num=0;if(!x){putchar('0');puts("");return;}
        while(x>0)CH[++Num]=x%10,x/=10;
        while(Num)putchar(CH[Num--]+48);
        puts("");
    }
    */
    inline ll read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    inline void P(int x)
    {
        Num=0;if(!x){putchar('0');puts("");return;}
        while(x>0)CH[++Num]=x%10,x/=10;
        while(Num)putchar(CH[Num--]+48);
        puts("");
    }
    //**************************************************************************************
    
    map<int,int> vis1;
    map<int,int> vis2;
    char s[100];
    int dx[4]={1,-1,0,0};
    int dy[4]={0,0,1,-1};
    struct node
    {
        int m[3][3];
        int x,y;
        int ha;
        int t;
    };
    node st;
    int check()
    {
        int a[9],t=0;
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                a[t++]=st.m[i][j];
        t=0;
        for(int i=0;i<9;i++)
            for(int j=i+1;j<9;j++)
                if(a[i]&&a[j]&&a[i]>a[j])
                    t++;
        return t&1;
    }
    int get_ha(node b)
    {
        int sum=0;
        int a[9],t=0;
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                a[t++]=b.m[i][j];
    
        ll N=1998585857;
        long long h=0;
        for(int i=0;i<9;i++)
            h=(h*12+(a[i])+N)%N;
        return h%N;
    }
    int main()
    {
        char ch;
        node aimm;
        aimm.m[0][0]=1;
        aimm.m[0][1]=2;
        aimm.m[0][2]=3;
        aimm.m[1][0]=4;
        aimm.m[1][1]=5;
        aimm.m[1][2]=6;
        aimm.m[2][0]=7;
        aimm.m[2][1]=8;
        aimm.m[2][2]=0;
        aimm.x=2;
        aimm.y=2;
        aimm.t=1;
        int aim=get_ha(aimm);
        aimm.ha=aim;
        while(cin>>ch)
        {
            vis1.clear();
            vis2.clear();
            s[0]=ch;
            for(int i=1;i<9;i++)
            {
                cin>>ch;
                s[i]=ch;
            }
            int m=0;
            for(int i=0;i<3;i++)
            {
                for(int j=0;j<3;j++)
                {
                    if(s[m]=='x')st.m[i][j]=0,st.x=i,st.y=j;
                    else st.m[i][j]=s[m]-'0';
                    m++;
                }
            }
    
            if(check())
            {
                printf("unsolvable
    ");
                continue;
            }
            st.t=1;
            st.ha=get_ha(st);
            vis1[st.ha]=1;
            vis2[aimm.ha]=1;
            queue<node> q;
            queue<node> q2;
            q2.push(aimm);
            q.push(st);
            while(!q.empty()||!q2.size())
            {
                if(!q.empty())
                {
                    node now=q.front();
                    /*
                    cout<<now.t<<" "<<1<<endl;
                    for(int i=0;i<3;i++)
                    {
                        for(int j=0;j<3;j++)
                        {
                            cout<<now.m[i][j];
                        }
                        cout<<endl;
                    }
                    cout<<endl;
                    */
                    if(vis2[now.ha])
                    {
                        //cout<<now.t<<" "<<"1231231"<<endl;
                        printf("%d
    ",now.t+vis2[now.ha]-2);
                        break;
                    }
                    q.pop();
                    for(int i=0;i<4;i++)
                    {
                        node next=now;
                        next.t++;
                        if(next.x+dx[i]<0||next.x+dx[i]>=3)
                            continue;
                        if(next.y+dy[i]<0||next.y+dy[i]>=3)
                            continue;
                        swap(next.m[next.x][next.y],next.m[next.x+dx[i]][next.y+dy[i]]);
                        next.ha=get_ha(next);
                        next.x+=dx[i];
                        next.y+=dy[i];
                        if(vis1[next.ha]>0)
                            continue;
                        vis1[next.ha]=next.t;
                        q.push(next);
                    }
                }
                if(!q2.empty())
                {
                    node now=q2.front();
                    /*
                    cout<<now.t<<" "<<2<<endl;
                    for(int i=0;i<3;i++)
                    {
                        for(int j=0;j<3;j++)
                        {
                            cout<<now.m[i][j];
                        }
                        cout<<endl;
                    }
                    cout<<endl;
                    */
                    if(vis1[now.ha])
                    {
                        //cout<<now.t<<" "<<"12312131"<<endl;
                        printf("%d
    ",now.t+vis1[now.ha]-2);
                        break;
                    }
                    q2.pop();
                    for(int i=0;i<4;i++)
                    {
                        node next=now;
                        next.t++;
                        if(next.x+dx[i]<0||next.x+dx[i]>=3)
                            continue;
                        if(next.y+dy[i]<0||next.y+dy[i]>=3)
                            continue;
                        swap(next.m[next.x][next.y],next.m[next.x+dx[i]][next.y+dy[i]]);
                        next.ha=get_ha(next);
                        next.x+=dx[i];
                        next.y+=dy[i];
                        if(vis2[next.ha]>0)
                            continue;
                        vis2[next.ha]=next.t;
                        q2.push(next);
                    }
                }
            }
        }
    }
  • 相关阅读:
    mysql练习题
    转 -day19--form&modelform
    day20--注册功能及首页
    day19-form表单&auth模块、项目初识
    day15-pymysql模块的使用
    第14天jquery+bootstrap
    第13天-js+jquery
    iTween基础之Punch(摇晃)
    iTween基础之Audio(音量和音调的变化)
    iTween基础之Rotate(旋转角度)
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4489790.html
Copyright © 2011-2022 走看看