【題目鏈接】:http://hihocoder.com/problemset/problem/1312?sid=1092363
【題意】
【題解】
定義一個(gè)A*函數(shù)
f = step+val
這里的val是當(dāng)前這個(gè)狀態(tài);每個(gè)點(diǎn)到目標(biāo)狀態(tài)的點(diǎn)的曼哈頓距離的絕對(duì)值;
(這個(gè)值肯定比真正需要花費(fèi)的路程短)
step就為當(dāng)前狀態(tài)花費(fèi)的步數(shù);
把普通隊(duì)列改成優(yōu)先隊(duì)列;
優(yōu)先處理f值小的狀態(tài);
f值相同的,優(yōu)先處理step值小的;
(也就是說(shuō)f值大的不是不處理了,而是放到后面再處理)
這樣就能較快地逼近目標(biāo)狀態(tài)了;
效果異常地棒
2s變成0.2s了!
【Number Of WA】
0
【完整代碼】
#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ms(x,y) memset(x,y,sizeof x)typedef pair<
int,
int> pii;
typedef pair<LL,LL> pll;
const int dx[
9] = {
0,
1,-
1,
0,
0,-
1,-
1,
1,
1};
const int dy[
9] = {
0,
0,
0,-
1,
1,-
1,
1,-
1,
1};
const int pre[
9][
2] =
{{
2,
2},{
0,
0},{
0,
1},{
0,
2},{
1,
0},{
1,
1},{
1,
2},{
2,
0},{
2,
1}
};
const double pi =
acos(-
1.0);
const int N =
110;
struct node
{
int a[
9],p,step,f;
friend bool operator < (node x,node y){
if (x.f==y.f){
if (x.step==y.step)
return true;
elsereturn x.step>y.step;}
elsereturn x.f>y.f;}
};node init;
priority_queue <node> dl;
map <int,int> dic;
int a[
9],goal;
int cs[
9] = {
1,
2,
3,
4,
5,
6,
7,
8,
0};
int has(
int *a)
{
int x =
0;rep1(i,
0,
8) x = x*
10 + a[i];
return x;
}
int val(
int *a)
{
int ret =
0;rep1(i,
0,
8){
int x = i/
3,y = i%
3;
if (a[i]==
0)
continue;ret+=
abs(pre[a[i]][
0]-x)+
abs(pre[a[i]][
1]-y);}
return ret;
}
int bfs()
{
while (!dl.empty()){
int p = dl.top().p;
int now = dl.top().step;node temp;rep1(i,
0,
8) temp.a[i] = dl.top().a[i];dl.pop();
if (p>
2){
int tp = p-
3;swap(temp.a[tp],temp.a[p]);
int xzt = has(temp.a);
if (xzt==goal)
return now+
1;
if (dic.find(xzt)==dic.end()){dic[xzt] = now+
1;temp.step = now+
1;temp.p = tp;temp.f = temp.step+val(temp.a);dl.push(temp);}swap(temp.a[tp],temp.a[p]);}
if (p<
6){
int tp = p+
3;swap(temp.a[tp],temp.a[p]);
int xzt = has(temp.a);
if (xzt==goal)
return now+
1;
if (dic.find(xzt)==dic.end()){dic[xzt] = now+
1;temp.step = now+
1;temp.p = tp;temp.f = temp.step+val(temp.a);dl.push(temp);}swap(temp.a[tp],temp.a[p]);}
if (p%
3!=
0){
int tp = p-
1;swap(temp.a[tp],temp.a[p]);
int xzt = has(temp.a);
if (xzt==goal)
return now+
1;
if (dic.find(xzt)==dic.end()){dic[xzt] = now+
1;temp.step = now+
1;temp.p = tp;temp.f = temp.step+val(temp.a);dl.push(temp);}swap(temp.a[tp],temp.a[p]);}
if (p%
3!=
2){
int tp = p+
1;swap(temp.a[tp],temp.a[p]);
int xzt = has(temp.a);
if (xzt==goal)
return now+
1;
if (dic.find(xzt)==dic.end()){dic[xzt] = now+
1;temp.step = now+
1;temp.p = tp;temp.f = temp.step+val(temp.a);dl.push(temp);}swap(temp.a[tp],temp.a[p]);}}
return -
1;
}
int main()
{ios::sync_with_stdio(
false),
cin.tie(
0);goal = has(cs);
int t;
cin >> t;
while (t--){dic.clear();rep1(i,
0,
8){
cin >> a[i];
if (a[i]==
0) init.p = i;}rep1(i,
0,
8) init.a[i] = a[i];init.step =
0,init.f = init.step+val(init.a);dic[has(init.a)] =
0;
if (has(init.a)==goal){
cout <<
0 << endl;
continue;}
while (!dl.empty()) dl.pop();dl.push(init);
int ans = bfs();
if (ans==-
1)
cout <<
"No Solution!"<<endl;
elsecout << ans << endl;}
return 0;
}
轉(zhuǎn)載于:https://www.cnblogs.com/AWCXV/p/7626359.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)
總結(jié)
以上是生活随笔為你收集整理的【hihocoder 1312】搜索三·启发式搜索(启发式搜索写法)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。