Topic Link: Portal
Test instructions
A nine Gongge, given your initial state and end state, each lateral move and vertical movement have a certain cost,
Ask for the minimum cost from the initial state to the end state.
Analysis:
BFS, with priority queue maintenance to reach the current state of the optimal value, with a hash to determine whether the current state has been reached.
The code is as follows:
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include < queue>using namespace Std;const int INF = 1e9+7777;int fac[9]= {1,1,2,6,24,120,720,5040,40320}; Cantor unfolded, used to hashstruct nod {int mp[9],pos,cost; BOOL operator < (const struct NOD &tmp) const {return this->cost > tmp.cost; }} p;int dx[4]= {1,-1,0,0};int dy[4]= {0,0,-1,1};int s[9],e[9];int cv,ch;int vis[40320*9+100];int getHashVal (int *a) {//h Ash gets the hash value. int val = 0; for (int i=0; i<9; i++) {int cnt=0; for (int j=0; j<i; j + +) cnt+= (A[j]>a[i]); Val+=cnt*fac[i]; } return Val; BOOL Check (NOD tmp) {int cnt = 0; for (int i=0; i<9; i++) cnt+= (Tmp.mp[i]==e[i]); return cnt==9;} int BFS (nod st) {priority_queue<nod> Q; Q.push (ST); Vis[gethashval (ST.MP)]=0; while (! Q.empty ()) {nod top = Q.top (); Q.pop (); if (check (top)) {return top.cost; } for (int i=0; i<4; i++) {int tmppos = Top.pos; int nowx = (top.pos/3+dx[i]+3)%3;//convert int nowy = top.pos%3+dy[i]; if (nowy==3) {nowy=0; nowx= (nowx+1)%3; } if (nowy==-1) {nowy=2; nowx= (nowx-1+3)%3; } swap (Top.mp[nowx*3+nowy],top.mp[tmppos]); if (i<2) TOP.COST+=CV; else top.cost+=ch; Top.pos=nowx*3+nowy; int val = gethashval (TOP.MP); if (Top.cost<vis[val]) {Q.push (top); Vis[val]=top.cost; } swap (Top.mp[nowx*3+nowy],top.mp[tmppos]); if (i<2) TOP.COST-=CV; else top.cost-=ch; Top.pos=tmppos; }}}nod init () {NOD St; for (int i=0; i<40320*9+100; i++) Vis[i]=inf; for (int i=0; i<9; i++) {st.mp[i]=s[i]; if (s[i]==0) st.pos=i; } st.cost=0; Return St;} int main() {while (~scanf ("%d%d", &CH,&CV)) {if (cv==0&&ch==0) break; for (int i=0; i<9; i++) scanf ("%d", s+i); for (int i=0; i<9; i++) scanf ("%d", e+i); printf ("%d\n", BFS (init ())); } return 0;} /*4 96 3 08 1 24 5 76 3 08 1 24 5 731 314 3 60 1 58 2 70 3 64 1 58 2 792 41 5 34 0 78 2 61 5 04 7 38 2 612 283 4 50 2 67 1 85 7 18 6 20 3 403196312*/
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Uvalive 6665 Dragon ' s Cruller (BFS + priority queue +hash)