hdu3567Eight II(八数码,IDA*)

本文详细介绍了如何使用IDA*算法解决不确定目标状态的八数码问题,通过计算曼哈顿距离进行剪枝,实现有效的状态搜索。文章提供了完整的AC代码示例,包括状态表示、目标状态设定、IDA*搜索过程及剪枝条件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接

题意

八数码问题,不过目标状态不定,保证有解

解题思路

和上一题类似,先算一下目标状态在跑IDA*即可,剪枝条件与上一题相同
参考

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];
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){
            cout << step+1 << endl;
            sta[step] = dir[i];
            cout << sta << endl;
            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]);
    }
}

int main(int argc, char const *argv[])
{
    int T = 0;
    cin >> T;
    int Case = 1;
    while(T--){
        memset(sta,0,sizeof(sta));
        string s1,s2;
        cin >> s1 >> s2;
        cout << "Case " << Case++ << ": ";
        if(s1==s2){
            cout << "0" << endl;
            cout <<endl;
            continue;
        }
        flag = 0;
        int bx,by;
        for(int i=0;i<s1.length();i++){
            if(s1[i]=='X'){
                G[i/3][i%3] = 0;
                bx = i/3;
                by = i%3;
            }else{
                G[i/3][i%3] = s1[i]-'0';
            }
        }
        for(int i=0;i<s2.length();i++){
            int w = 0;
            if(s2[i]=='X'){
                w = 0;
            }else{
                w = s2[i]-'0';
            }
            goal[w][0] = i/3;
            goal[w][1] = i%3;
        }
        int top = 0;
        while(++top){
            idastar(bx,by,-1,0,top);
            if(flag)
                break;
        }
    }
    
    return 0;
}

转载于:https://www.cnblogs.com/django-lf/p/9786590.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值