BZOJ 1054 HAOI2008 移动玩具

本文介绍了一个类似八数码游戏的问题解决方法,通过使用广度优先搜索(BFS)算法结合状态判重来解决15拼图游戏。采用二进制哈希的方式对16个拼图的状态进行编码,并利用队列实现状态的遍历。

题目类似于八数码,BFS+判重。

可以直接把16个数字当成二进制Hash。

#include <cstdio>
#include <algorithm>
#include <map>
#include <queue>
#define up(a,b,c) for(int c=a;c<=b;++c)
#define down(a,b,c) for(int c=a;c>=b;--c)
using namespace std;

map<int,bool>vis;

struct node{
    int State[5][5];
    int Code,Step;
}Start,End;

int fx[]={0,0,-1,0,1},fy[]={0,-1,0,1,0};
int Out;

int MakeCode(node a){
    //这里MakeCode是将16个数转化为2进制
    //但是如果第一位是0 那么就无法进行了 0<<1 0<<2都是0啊
    //所以前置增加一位数字1 也就是二进制是17位的
    //不会爆int 因为1<<17最大也是就是13W左右 
    int Code=1;
    up(1,4,i){
        up(1,4,j){
            Code<<=1;
            if(a.State[i][j]) Code|=1;
        }
    }
    return Code;
}

bool Can(int x,int y){
    if(x<1 || y<1 || x>4 || y>4) return false;
    return true;
}

void SWAP(int &a,int &b){
    int c = a;
    a = b;
    b = c;
}

void BFS(){
    if(Start.Code==End.Code) return;
    queue<node>Q;
    Q.push(Start);
    while( !Q.empty() ){
        node now = Q.front();
        now.Step++;
        Q.pop();
        up(1,4,i){
            up(1,4,j){
                if(now.State[i][j]){
                    up(1,4,k){
                        int x = i+fx[k];
                        int y = j+fy[k];
                        if( Can(x,y) ){
                            SWAP(now.State[i][j],now.State[x][y]);
                            int Code = MakeCode(now);
                            if(Code==End.Code){
                                End.Step = now.Step;
                                return;
                            }
                            if(!vis[Code]){
                                vis[Code]=1;
                                Q.push(now);
                            }
                            SWAP(now.State[i][j],now.State[x][y]);
                        }
                    }
                }
            }
        }
    }
}

void init(){
    char s[23];
    up(1,4,i){
        scanf("%s",s+1);
        up(1,4,j){
            Start.State[i][j] = s[j]-'0';
        }
    }
    Start.Step=0;
    int CODE = MakeCode(Start);
//    printf("开始:%d\n",CODE);
    Start.Code=CODE;
    vis[CODE]=1;
    up(1,4,i){
        scanf("%s",s+1);
        up(1,4,j){
            End.State[i][j] = s[j]-'0';
        }
    }
    CODE = MakeCode(End);    
//    printf("结束:%d\n",CODE);
    End.Code=CODE;
    vis[CODE]=1;
}

int main(){
    init();
    BFS();
    printf("%d\n",End.Step);
    return 0;
    
}

 

转载于:https://www.cnblogs.com/OIerLYF/p/7510582.html

内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值