zoukankan      html  css  js  c++  java
  • hdu1043Eight(八数码,IDA*)

    题目链接

    题意

    经典的八数码的题目,还要判断是否有解,wiki链接

    解题思路

    用IDA*算法来解决,先算出当前状态和目标状态的哈曼顿距离,当距离为0时即解出答案。
    有两个可以剪枝的条件:

    • 下一个方向和当前的方向不能相反
    • 当前的步数加上当前的哈曼顿距离不能大于初始状态的哈曼顿距离

    关于8数码是否有解,可参考这篇文章

    AC代码

    #include<vector>
    #include<algorithm>
    #include<cstdio>
    #include<iostream>
    #include<set>
    #include<cstring>
    #include<functional>
    #include<map>
    #include<cmath>
    #include<string>
    #include<queue>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    typedef pair<int,pii> PII;
    const int maxn = 1e6+5;
    int goal[10][2] = {{2,2},{0,0},{0,1},{0,2}, {1, 0}, {1, 1}, {1, 2}, {2, 0}, {2, 1}};
    int G[10][10];
    int dx[] = {1,0,0,-1};
    int dy[] = {0,-1,1,0};
    char dir[] = {'d','l','r','u'};
    
    int manhattan()
    {
        int sum = 0;
        for(int i=0;i<3;i++){
            for(int j=0;j<3;j++){
                int w = G[i][j];
                if(w==0)continue;
                sum += abs(goal[w][0] - i) + abs(goal[w][1] - j);
            }
        }
        return sum;
    }
    char sta[500];
    bool flag = 0;
    void idastar(int x,int y,int pre,int step,int top)
    {
        if(flag)return;
        for(int i=0;i<4;i++){
            if(flag)return;
            int nx = x + dx[i];
            int ny = y + dy[i];
            if(nx > 2||ny>2||nx < 0||ny<0)continue;
            if(pre + i == 3)continue;
            swap(G[x][y],G[nx][ny]);
            int mht = manhattan();
            if(mht==0){
                sta[step] = dir[i];
                printf("%s
    ",sta);
                flag = 1;
                return;
            }
            if(mht + step <= top){
                if(flag) return;
                sta[step] = dir[i];
                idastar(nx,ny,i,step+1,top);
            }
            swap(G[x][y],G[nx][ny]);
        }
    }
    
    bool isok(int *state)
    {
        int sum = 0;
        for(int i=0;i<9;i++){
            int num = 0;
            if(state[i]==0)continue;
            for(int j=i+1;j<9;j++){
                if(state[i] > state[j]&&state[j])
                    num++;
            }
            sum += num;
        }
        return sum%2;
    }
    
    int main(int argc, char const *argv[])
    {
        char s[100];
        while(~scanf(" %c",&s[0])){
            memset(sta,0,sizeof(sta));
            for(int i=1;i<9;i++){
                scanf(" %c",&s[i]);
            }
            flag = 0;
            int bx,by;
            int state[10];
            for(int i=0;i<9;i++){
                if(s[i]=='x'){
                    G[i/3][i%3] = 0;
                    state[i] = 0;
                    bx = i/3;
                    by = i%3;
                }else{
                    G[i/3][i%3] = s[i]-'0';
                    state[i] = s[i] - '0';
                }
            }
            
            if(isok(state)){
                printf("unsolvable
    ");
                continue;
            }
            int ans = manhattan();
            if(ans==0){
                printf("
    ");
                continue;
            }
    
            int top = 0;
            while(++top){
                idastar(bx,by,-1,0,top);
                if(flag)
                    break;
            }
        }
        
        return 0;
    }
    
  • 相关阅读:
    centos mongodb
    CentOS YUM 安装 TOMCAT6
    Linux切换工作目录命令:cd
    CentOS中JAVA_HOME的环境变量设置
    用Navicat for MySQL 连接 CentOS 6.5
    CentOS上开启MySQL远程访问权限
    centos7下yum安装mysql
    long数值 转换为时间
    安卓开发_浅谈AsyncTask
    ScrollView与ListView的事件冲突
  • 原文地址:https://www.cnblogs.com/django-lf/p/9786583.html
Copyright © 2011-2022 走看看