雙向廣搜很早之前就像學習,但蒟蒻這道今天才會寫(汗。。。)
八數碼問題在oi界也算是婦孺皆知,有啟發式搜尋和dbfs兩種解法,題目不在詳細介紹,在這裡給出我的解法
codevs 1225 八數碼難題
比較原始的八數碼,目標狀態為123804765(即蛇形排列),雙向廣搜顧名思義,就是兩頭同時進行廣搜,我們有了起點狀態和目標狀態,可以同時擴充套件,這道擴充套件出同乙個葉子節點,注意hash判重,queue中的st為步數,col表示是從正序擴充套件而來還是從逆序擴充套件而來,exist存放編號,一旦出現hash值相同但col不同,就查詢出來節點編號,把st相加即為結果。 code:
#include#include#includeusing namespace std;
int fac[10]=;
int en[4][4]=,st[4][4],head,tail;
int dx[5]=,dy[5]=;
int exist[500001][2];
struct hpqueue[500001];
int hash(int i)
return sum;
}void init()
}int bfs()
if (en[i][j]==0)
}queue[1].col=0; queue[2].col=1;
queue[1].st=queue[2].st=0;
memset(exist,0,sizeof(exist));
exist[hash(1)][0]=1; exist[hash(2)][1]=2; step=0;
while (head=1&&bx1+dx[j]<=3&&by1+dy[j]>=1&&by1+dy[j]<=3)
} }
head=e;
}return -1;
}int main()
poj 1077 eight 輸出路徑的八數碼,稍麻煩 code:
#include#include#includeusing namespace std;
int fac[10]=;
int en[4][4]=,st[4][4],head,tail;
int dx[5]=,dy[5]=;
int exist[500001][2];
struct hpqueue[500001];
int hash(int i)
return sum;
}void init()
}void print1(int mid)
void print2(int mid)
int bfs()
if (en[i][j]==0)
}queue[1].col=0; queue[2].col=1;
queue[1].st=queue[2].st=0;
memset(exist,0,sizeof(exist));
exist[hash(1)][0]=1; exist[hash(2)][1]=2; step=0;
while (head=1&&bx1+dx[j]<=3&&by1+dy[j]>=1&&by1+dy[j]<=3)
if (queue[tail].col==1)
temp=hash(tail);
if (exist[temp][queue[tail].col])
tail--;
else
else
return step+queue[exist[temp][1-queue[tail].col]].st;
}}
} }
head=e;
}return -1;
}int main()
雙向廣搜 八數碼
雙向廣搜還是乙個很神奇的東西 判重更神奇 雙廣僅適用於有目標狀態的題目 include include include include include include include include include include using namespace std const int maxx...
康托展開 雙向廣搜
康托展開 公式 x a n n 1 a n 1 n 2 a i i 1 a 2 1 a 1 0 利用這個公式,我們可以求出在一列數中,已知的這一列數是這列數的全排列的字典序中的的幾個。我們可以應用康拓展開來求出一列數的全排列,也可以用康托展開進行判重。int kt int n,int s 擴充套件乙...
HDU 1401 Solitaire (雙向廣搜)
題意 在二維8 8的方格,給定4個初始點和4個最終點,問在8步內是否能從初始點走到最終點,雙向廣搜 同時對初始點和最終點廣搜4步,對每一步記錄狀態,初始點為 1 最終點為 2 若在限定時間內初始點的狀態能到達 2 或最終點的狀態能到達 1 則為yes!要記得排序。include include in...