錛?錛?鐢ˋ*綆楁硶錛?浼頒環(huán)鍑芥暟閫?#8220;Hamilton璺濈”姣旈夌敤“鍦ㄩ敊璇柟鍚勫唴鐨勬暟瀛楁暟鐩?#8221;寮哄緢澶氥?
錛?錛堿*綆楁硶鐨勫叧閿槸瑕佽兘澶熶嬌“鎵懼埌鑰楄垂鏈灝忕殑鑺傜偣”鍜?#8220;鍒ゆ柇鏄惁瀛愯妭鐐瑰凡緇忓瓨鍦?#8221;鐨勭畻娉曠殑鏁堢巼灝藉彲鑳介珮錛屼負(fù)姝わ紝緗戜笂涓嶅皯璧勬枡寤鴻閲囩敤Binary Heap鎴朒ash table絳夋暟鎹粨鏋勶紝鐒惰屽崟鐙嬌鐢ㄤ換浣曚竴縐嶆暟鎹粨鏋勶紝閮芥湁涓瀹氱殑緙洪櫡錛屽皢Heap鍜孒ash鑱斿悎璧鋒潵浣跨敤錛屽簲璇ュ彲浠ユ彁楂樹笉灝戞晥鐜囥傚叿浣撳涓嬶細(xì)
1銆傚緩涓寮燞ash琛紝瀛樻斁娌′竴涓妭鐐圭殑鍏蜂綋淇℃伅錛屽褰撳墠鐘舵併佺埗鑺傜偣鍦ㄨ〃涓殑浣嶇疆絳夈?
2銆俹pen琛ㄤ腑瀛樻斁鐫涓浜涜妭鐐癸紝榪欎簺鑺傜偣涓嶅悓浜嶩ash琛ㄤ腑鐨勮妭鐐癸紝鍙互灝嗗畠鐞嗚В涓烘槸Hash琛ㄤ腑鑺傜偣鐨勭儲寮曪紝瀹冨彧鍖呭惈鑺傜偣鐨勪及浠峰拰鑺傜偣鍦℉ash琛ㄤ腑鐨勪綅緗紝榪欎簺鑺傜偣鎸変及浠鋒帓鍒楁垚鍫嗭紙Heap錛夈?
3銆傛病蹇呰鍐嶅緩涓涓猚losed琛ㄣ?
榪欐牱錛岀▼搴忕殑嫻佺▼灝卞彲浠ュ啓鎴愶細(xì)
鍒濆鍖朒ash琛ㄥ拰open琛紱
灝嗘牴鑺傜偣鏀懼叆Hash琛ㄥ拰open琛紱
found = false;
while(open琛ㄤ笉絀? {
浠巓pen琛ㄤ腑寰楀埌鑰楄垂鏈浣庣殑鑺傜偣鐨勭儲寮昪ur; // O(1)
浠巓pen琛ㄤ腑鍒犻櫎鑰楄垂鏈浣庣殑鑺傜偣; // O(logN)
for 姣忎釜cur鐨勫瓙鑺傜偣now do {
if ( now 鏄洰鏍囪妭鐐?) {
鎵撳嵃杈撳嚭;
found = true;
緇撴潫鎼滅儲;
}
if( now 涓嶅湪Hashtable涓?) { // O(1)
灝唍ow鎻掑叆Hashtable涓? // O(1)
灝唍ow鐨勭儲寮曟斁鍏pen琛ㄤ腑; // O(logN)
} else if( now姣擧ashtable涓殑鑺傜偣浼?) {
if( 鍘熻妭鐐瑰湪open琛ㄤ腑 ) { // O(N)
鐢╪ow鏇夸唬鍘熸潵鑺傜偣; // O(1)
鍦╫pen涓璸ush_heap鏉ユ洿鏂皁pen琛ㄧ殑欏哄簭; // O(logN)
}
}
}
}
if( !found ) 杈撳嚭 "鏃犺В";
鍙互鐪嬪埌錛岃櫧鐒舵煡鎵緊pen琛ㄤ腑宸插瓨鍦ㄧ殑鑺傜偣浠嶇劧涓篛(N)錛?浣嗘槸褰搉ow宸插瓨鍦ㄦ椂錛宯ow姣攐pen琛ㄤ腑鑺傜偣浼樼殑姒傜巼鏄緢灝忕殑錛屼簨鍏堢敤O(1)鐨勬椂闂村垽鏂紝灝卞彲浠ラ伩鍏嶇敤O(N)鐨勬椂闂存潵鏌ユ壘錛屼粠鑰屾彁楂樹簡鏁堢巼錛堣繖寰堝儚鏄疌PU鐨凜ache鐨勫伐浣滃師鐞嗭級銆?
鍏蜂綋紼嬪簭濡備笅錛?/p>
#include "stdafx.h"
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
#include <cassert>
using namespace std;
struct OpenNode{
int cost, point;
OpenNode(){}
OpenNode( int cost, int point ){
this->cost = cost;
this->point = point;
}
};
bool operator<( const OpenNode& a, const OpenNode& b ){
return a.cost > b.cost;
}
bool operator==(const OpenNode& a, int c){
return a.point == c;
}
struct HashNode{
char state[3][3];
int g, h, par, dir,x,y;
bool used;
HashNode(){
used=false;
}
};
int dx[] = { -1,0,1,0 },
dy[] = { 0,1,0,-1 }; // u r d l
const int HASH_SIZE = 39999;
HashNode List[HASH_SIZE];
int factorial[] = {1,1,2,6,24,120,720,5040,40320};
/*int hash( char state[3][3] ){
int ret = 0;
char *p, *q;
for(p=&state[0][0];p<=&state[2][2];p++){
int cnt = 0;
for(q=&state[0][0]; q<p; q++) if( *q<*p ) cnt++;
ret += factorial[&state[2][2]-p]*(*p-cnt);
}
return ret;
}*/
bool eq( char a[3][3], char b[3][3] ){
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;
}
int hash( char state[3][3] ){
char* p = &state[0][0];
int ret = p[0] * 7 + p[1] * 17 + p[2] * 47 + p[3] * 117 + p[4] * 217 + p[5]
* 977 + p[6] * 1299 + p[7] * 5971 + p[8] * 7779;
ret %= HASH_SIZE;
while( List[ret].used && !eq(List[ret].state , state) )
ret= (ret+1) % HASH_SIZE;
return ret;
}
int h( char state[3][3] ){
int ret = 0;
for(int x=0;x<3;x++)
for(int y=0;y<3;y++) if( state[x][y]!=0 )
ret += abs((state[x][y]-1)/3-x) +abs((state[x][y]-1)%3-y);
return ret;
}
void output( int i ){
string res;
while(List[i].dir>=0){
res+= List[i].dir==0?'u':List[i].dir==1?'r':List[i].dir==2?'d':'l';
i = List[i].par;
}
reverse( res.begin(), res.end() );
cout<<res<<endl;
}
bool solvable( char state[3][3] ){
int t = 0;
for(char* i=&state[0][0];i<&state[2][2];i++)
for(char* j=i+1;j<=&state[2][2];j++)
if(*i!=0 && *j!=0 && *i>*j) t++;
if(t%2) return false;
return true;
}
vector<OpenNode> open;
int main(){
string init;
getline( cin, init );
HashNode now;
int cnt=0;
for(int i=0;i<init.size();i++) {
if(init[i] == 'x') {
now.state[cnt/3][cnt%3] = 0;
now.x = cnt /3;
now.y = cnt %3;
cnt++;
} else if(init[i]!=' ') {
now.state[cnt/3][cnt%3] = init[i] - '0';
cnt++;
}
}
if( !solvable(now.state) ) {
cout<<"unsolvable"<<endl;
return 0;
}
now.g = 0;
now.h = h(now.state);
now.par = -1;
now.dir = -1;
now.used = true;
int i = hash(now.state);
List[i] = now;
open.push_back(OpenNode(now.g+now.h,i));
while(!open.empty()){
int cur = open.front().point;
pop_heap( open.begin(), open.end() );
open.erase( open.end()-1 );
for(int i=0;i<4;i++){
now = List[cur];
int x = now.x+dx[i];
int y = now.y+dy[i];
if(x<0||x>2||y<0||y>2) continue;
swap( now.state[x][y], now.state[now.x][now.y] );
now.x = x;
now.y = y;
now.h = h( now.state );
now.g++;
now.par = cur;
now.dir = i;
int hashcode = hash( now.state );
if( now.h == 0 ){
List[hashcode] = now;
output( hashcode );
return 0;
} else if( !List[hashcode].used ){
List[hashcode] = now;
open.push_back( OpenNode(now.h+now.g,hashcode) );
push_heap( open.begin(), open.end() );
} else if( List[hashcode].g+List[hashcode].h > now.g+now.h ){
List[hashcode] = now;
vector<OpenNode>::iterator it = find( open.begin(), open.end(), hashcode );
if(it==open.end()) continue;
push_heap( open.begin(), it+1 );
}
}
}
cout<<"unsolvable"<<endl;
return 0;
}