zoukankan      html  css  js  c++  java
  • P1379 八数码难题

    题目大意:给你一个矩阵,问最少要几步将矩阵变为123804765,每次操作可将0与上下左右各个数调换。

    思路:这道题深搜深度非常大,广搜分类太多,导致无论深搜还是广搜都会TLE,那么我们应该找一个综合广搜和深搜优点的算法——迭代加深搜索。我们枚举移动几次会到达目标节点,一旦搜到次数大于枚举的数就return。

    但裸的迭代加深搜索可能过不了,所以这时就需要一个更强力的做法:IDA*。在我理解,它其实很像对迭代加深搜索的剪枝:你预估一下当前情况到目标情况所需的步数,如果这个步数加上你已经枚举的深度是大于迭代的值的话就return;而这个预估的值就是h函数,他必须要比实际值小,但越接近实际值越好,所以IDA*的搜索复杂度取决于h函数的设定。

    这里我们设当前矩阵的点和目标矩阵所对应的点不同的个数为h函数,易证这个函数是正确的,但却不是最优的,复杂度O(可过),800多ms跑得飞快。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int MaxN=10;
    int n[MaxN][MaxN],a[MaxN][MaxN],nx,ny,now;
    int ffx[5]={0,1,-1,0,0},
        ffy[5]={0,0,0,1,-1};
    int calh(){
        int sum=0;
        for(int i=1;i<=3;++i){
            for(int j=1;j<=3;++j){
                if(a[i][j]!=n[i][j]) ++sum;
            }
        }
        return sum;
    }
    int dfs(int xx,int yy,int x,int y,int id){
        if(now+calh()-1>id) return 0;//减去空格移动的1
        if(calh()==0) return 1;
        for(int i=1;i<=4;++i){
            int dx=x+ffx[i],dy=y+ffy[i];
            if(dx<=0||dx>3||dy<=0||dy>3||(xx==dx&&yy==dy)) continue;
            ++now;swap(a[x][y],a[dx][dy]);if(dfs(x,y,dx,dy,id)) return 1;
            now--;swap(a[x][y],a[dx][dy]);
        }
        return 0;
    }
    int main(){
        char c[MaxN];
        n[1][1]=1;n[1][2]=2;n[1][3]=3;
        n[2][1]=8;n[2][2]=0;n[2][3]=4;
        n[3][1]=7;n[3][2]=6;n[3][3]=5;
        for(int i=1;i<=9;++i) cin>>c[i];
        a[1][1]=c[1]-'0';a[1][2]=c[2]-'0';a[1][3]=c[3]-'0';
        a[2][1]=c[4]-'0';a[2][2]=c[5]-'0';a[2][3]=c[6]-'0';
        a[3][1]=c[7]-'0';a[3][2]=c[8]-'0';a[3][3]=c[9]-'0';
        for(int i=1;i<=3;++i) for(int j=1;j<=3;++j) if(a[i][j]==0) nx=i,ny=j;
        for(int i=1;i<=1e5;++i){
            now=0;
            if(dfs(0,0,nx,ny,i)) break;
        }
        printf("%d
    ",now);
    }
  • 相关阅读:
    特殊方法(双下方法)
    反射
    属性
    类方法、静态方法
    封装
    python接口类,抽象类
    Yii2基本概念之——事件(Event)
    Yii2基本概念之——行为(Behavior)
    yii2 migrate 数据库迁移的简单分享
    Yii2.0 RESTful API 之速率限制
  • 原文地址:https://www.cnblogs.com/X-rice/p/11219384.html
Copyright © 2011-2022 走看看