zoukankan      html  css  js  c++  java
  • 【P1379】八数码难题(搜索+暴力)

    这个题真是。。。

    不想说什么了,及其复杂和烦人的一道题。基础思路就是bfs,用两个队列分别进行0的位置的计算和每一步的状态。。然而这个题最重要的一点在于判重,实际上可以康托展开用全排列的个数进行判重,这样也貌似好操作一些,但是时间短技术差想不到怎么办,通过计算空间,我们发现,可以暴力开一个9维bool数组进行暴力判重,至于怎么判也就不需要多说了,这种状态出现过就可以了。

    ###错误点1:bool数组不打标记,一直mle。。。

    ###错误点2:居然会有一开始就是目标状态的点。。。没有特判。。。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #define re register
    #define ll long long
    using namespace std;
    short n,m,ans,t,d,l,h[5000001][4],x[4000001][3][3];
    int dx[5]={0,1,0,-1,0};
    int dy[5]={0,0,1,0,-1};
    char a[10][10];
    bool b[9][9][9][9][9][9][9][9][9];
    int main()
    {
        for(int i=0;i<3;i++)
        {
            for(int j=0;j<3;j++)
            {
                cin>>a[i][j];
                x[1][i][j]=a[i][j]-'0';
                if(a[i][j]=='0')
                {
                    h[1][1]=i;
                    h[1][2]=j;
                }
            }
        }
        int head=0,tail=1;
        if(x[tail][0][0]==1&&x[tail][0][1]==2&&x[tail][0][2]==3&&x[tail][1][0]==8&&x[tail][1][1]==0&&x[tail][1][2]==4&&x[tail][2][0]==7&&x[tail][2][1]==6&&x[tail][2][2]==5)
                    {
                        cout<<0;
                        return 0;
                    }
        h[1][3]=0;
        while(head<tail)
        {
            int nx=h[++head][1];
            int ny=h[head][2];
            int dep=h[head][3];
            for(re int i=1;i<=4;i++)
            {
                int tx=nx+dx[i];
                int ty=ny+dy[i];
                if(tx>=0&&tx<3&&ty>=0&&ty<3)
                {
                    h[++tail][1]=tx;
                    h[tail][2]=ty;
                    h[tail][3]=dep+1;
                    for(re int j=0;j<3;j++)
                    {
                        for(re int k=0;k<3;k++)
                        {
                            x[tail][j][k]=x[head][j][k];
                        }
                    }
                    x[tail][nx][ny]=x[tail][tx][ty];
                    x[tail][tx][ty]=0;
                    if(b[x[tail][0][0]][x[tail][0][1]][x[tail][0][2]][x[tail][1][0]][x[tail][1][1]][x[tail][1][2]][x[tail][2][0]][x[tail][2][1]][x[tail][2][2]])
                    {
                        tail--;
                        continue;
                    }
                    b[x[tail][0][0]][x[tail][0][1]][x[tail][0][2]][x[tail][1][0]][x[tail][1][1]][x[tail][1][2]][x[tail][2][0]][x[tail][2][1]][x[tail][2][2]]=1;
                    if(x[tail][0][0]==1&&x[tail][0][1]==2&&x[tail][0][2]==3&&x[tail][1][0]==8&&x[tail][1][1]==0&&x[tail][1][2]==4&&x[tail][2][0]==7&&x[tail][2][1]==6&&x[tail][2][2]==5)
                    {
                        cout<<dep+1;
                        return 0;
                    }
                }
            }
        }
    }
  • 相关阅读:
    Linux makefile教程之概述一[转]
    Valid Parentheses
    Letter Combinations of a Phone Number
    机器学习经典分类算法 —— C4.5算法(附python实现代码)
    3Sum Closest
    3Sum
    Integer to Roman
    寒假文献阅读(四)
    Longest Common Prefix
    Roman to Integer
  • 原文地址:https://www.cnblogs.com/victorique/p/8427051.html
Copyright © 2011-2022 走看看