八数码难题
一种名为A*的搜索方法。
A星是为了解决那些搜索树很宽很深、但答案比较浅的搜索问题。A星的核心有两个,一个是迭代加深,这一步是为了使得搜索树变浅(埃及分数那道题用了);另一个是估价函数,这是为了修剪那些不可能通向正确答案的状态,使搜索树变窄。这样一来,又窄又矮的搜索树自然跑得就快了。
迭代加深很好理解,而估价函数的含义就是快速求出一个可能的值,这个值尽量靠近最少步数但一定要不大于,同时还需要快速求得。比如这道题的估价函数设置为不同点的个数,因为每次操作都只能把一个非0点归到正确位置上,所以所用的最少步数不会比不在正确位置上的非0点的个数要少。
效果上,就这道题的数据而言,估价函数使时间从2s到200ms。
一般来说也可以用双向搜索的方式解决,而且似乎更快。但我不想写。
#include<bits/stdc++.h>
//#define feyn
using namespace std;
inline void read(int &wh){
wh=0;int f=1;char w=getchar();
while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
wh*=f;return;
}
inline int max(int s1,int s2){
return s1<s2?s2:s1;
}
inline void swap(int &s1,int &s2){
int s3=s1;s1=s2;s2=s3;return;
}
int a[3][3],b[3][3]={{1,2,3},{8,0,4},{7,6,5}};
inline bool check(){
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
if(a[i][j]^b[i][j])return false;
}
}
return true;
}
inline int test(){
int an=0;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
if(a[i][j]^b[i][j])an++;
}
}
return an-1;
}
int limit,f[4][2]={{0,-1},{1,0},{-1,0},{0,1}};bool ok;
void dfs(int wh,int last,int x,int y){
if(wh==limit){if(check())ok=true;return;}
//if(ok||wh+test()>limit)return;
for(int i=0;i<4;i++){
if(i+last==3||ok)continue;
int ax=x+f[i][0],ay=y+f[i][1];
if(ax<0||ay<0||ax>2||ay>2)continue;
swap(a[x][y],a[ax][ay]);
dfs(wh+1,i,ax,ay);
swap(a[x][y],a[ax][ay]);
}
}
signed main(){
#ifdef feyn
freopen("in.txt","r",stdin);
#endif
int x,y;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
a[i][j]=getchar()-'0';
if(a[i][j]==0)x=i,y=j;
}
}
while(!ok){
dfs(0,-1,x,y);
if(ok)printf("%d",limit);
limit++;
}
return 0;
}
一如既往,万事胜意
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具