題目描述[八數碼問題]
八數碼問題,即在乙個3×3的矩陣中有8個數(1至8)和乙個空格,現在要你從乙個狀態轉換到另乙個狀態,每次只能移動與空格相鄰的乙個數字到空格當中,問題是要你求從初始狀態移動到目標狀態所需的最少步數。如下圖所示。
1 2 31
2 3
8 0 47
8 4
7 6 50
6 5
初始狀態 目標狀態
如上圖所示的資料以矩陣形式給出。現在給出分別代表初始狀態和目標狀態的兩個3*3的矩陣,請給出兩個矩陣相互轉化的最少步數。
輸入 第1行-第3行:3個用空格分隔的整數,代表初始狀態相應位置的數字,0代表空格
第4行-第6行:3個用空格分隔的整數,代表終止狀態相應位置的數字,0代表空格
輸出 第1行:乙個整數,最小轉換步數,如不能到相互轉化則輸出」impossible」
樣例輸入
1 2 3
8 0 4
7 6 5
1 2 3
7 8 4
0 6 5
樣例輸出
2 思路:此題為典型的廣度搜尋,由於狀態較多,因此如何解決判重問題極為重要,可利用dbfs來減小時間複雜度。
判重:採用排列組合的方式,將八數碼的九格換成九位數,共有9!種排列方式,由小到大排列,找到他的所處位置
雜湊判重:運用雜湊表,雜湊鏈,每乙個八數碼狀態對應乙個編號,取乙個恰當的mod數,利用鏈式處理衝途
採用優先佇列,先判斷 f=g+h,f代表到目標狀態差值,g代表不相同的各數,h代表第幾步了,f越小,越靠近目標
#include
#include
#include
#include
#include
#include
using namespace std;
const int hashsize=100003;
struct node
};struct hashlist
;hashlist *(hl[100003]);
priority_queueq;
int dx[4]=;
int dy[4]=;
node goal;
node star;
int jop1(int
s[9])
total+=cnt;
}return total%2;
}int judge(int bh)
else
p=new hashlist;
p->next=hl[temp];
hl[temp]=p;
return
1; }
}int bianhao(int
s[9])
int df(int
s[9])
return
8-cnt;
}int bfs()//廣度搜尋
}int
x=z/3;
inty=z%3;
int newx=x+dx[i];
int newy=y+dy[i];
if(newx>=0&&newx<3&&newy>=0&&newy<3)
*/if(memcmp(n.state,goal.state,9
*sizeof(int))==0) return n.step;
q.push(nn);}}
}}
}return -1;
}int main()
for(int j=0;j<9;j++) scanf("%d",&goal.state[j]);
if(jop1(star.state)^jop1(goal.state))
int flag=bfs();
if(flag!=-1) printf("%d\n",flag);
}
歡迎使用CSDN markdow
本markdown編輯器使用stackedit修改而來,用它寫部落格,將會帶來全新的體驗哦 markdown 是一種輕量級標記語言,它允許人們使用易讀易寫的純文字格式編寫文件,然後轉換成格式豐富的html頁面。維基百科 使用簡單的符號標識不同的標題,將某些文字標記為粗體或者斜體,建立乙個鏈結等,詳細...
歡迎毛毛與妞妞使用CSDN markdown編輯器
建立乙個自定義列表 如何建立乙個註腳 注釋也是必不可少的 katex數學公式 新的甘特圖功能,豐富你的文章 uml 圖表 flowchart流程圖 匯出與匯入 你好!這是你第一次使用markdown編輯器所展示的歡迎頁。如果你想學習如何使用markdown編輯器,可以仔細閱讀這篇文章,了解一下mar...
歡迎使用CSDN markdow1n編輯器
本markdown編輯器使用stackedit修改而來,用它寫部落格,將會帶來全新的體驗哦 markdown 是一種輕量級標記語言,它允許人們使用易讀易寫的純文字格式編寫文件,然後轉換成格式豐富的html頁面。維基百科 使用簡單的符號標識不同的標題,將某些文字標記為粗體或者斜體,建立乙個鏈結等,詳細...