日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HDU - 1043 Eight(bfs打表)

發布時間:2024/4/11 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HDU - 1043 Eight(bfs打表) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接:點擊查看

題目大意:八數碼經典問題,給出一個3*3的矩陣,其中隨機分布著1~8的數字以及一個空位(我們用x來表示空位),在整個矩陣中,每一次操作都可以將x和他附近的方塊互換,問經過多少次操作可以將當前的狀態變為順序狀態,即

1? ?2? ?3

4? ?5? ?6

7? ?8? ?x

求所需操作的最小次數以及每次的步驟

題目分析:一看到這個題目首先想到每一種情況都可以表示為一種狀態,一提到狀態我們就可以用bfs進行展開,這個題不得不說我優化了一個下午,一開始沒多想,直接用A*做的,想連一下A*算法,結果寫完之后T掉了,我就感覺我的估價函數找的不太對,就去網上搜了大佬的博客,比這寫了一下估價函數,結果變成WA了,有點自閉,就去網上搜了搜八種方法解八數碼問題,就選了現在的這個,先用bfs打個表,然后就可以O(1)查詢了,省去了大量的bfs步驟,不過我在打表的時候用到了unordered_map,但是poj不讓用這個東西。。所以在poj上還是T掉了,在hdu上的以200多ms的時間A掉了,我又試了試用map交了一發,在hdu上還是A了,只不過時間變成了500ms。。因為網上的正解都是用了康托展開維護狀態的,但我不會,只能用最菜的map來維護所謂的雙向哈希了,預處理bfs打個路徑表,然后直接問什么輸出什么就可以了

代碼:

#include<iostream> #include<cstdlib> #include<string> #include<cstring> #include<cstdio> #include<algorithm> #include<climits> #include<cmath> #include<cctype> #include<stack> #include<queue> #include<list> #include<vector> #include<set> #include<map> #include<sstream> #include<unordered_map> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=4e5+100;const int b[4][2]={0,1,0,-1,1,0,-1,0};const char p[5]="lrud";const string target="123456780";unordered_map<string,int>vis;struct Node {int pre;int dir;Node(int PRE,int DIR){pre=PRE;dir=DIR;}Node(){} }path[N];void bfs() {int cnt=0;//用一個cnt變量輔助維護模擬鏈表vis.clear();queue<string>q;q.push(target);//以最終狀態為起點,bfs展開即可,時間復雜度為9!,不到4e5path[cnt].pre=-1;path[cnt].dir=-1;vis[target]=cnt++;while(!q.empty()){string cur=q.front();q.pop();int pos;for(pos=0;pos<9;pos++)if(cur[pos]=='0')break;int x=pos/3;int y=pos%3;for(int i=0;i<4;i++){int xx=x+b[i][0];int yy=y+b[i][1];if(xx<0||yy<0||xx>=3||yy>=3)continue;int ppos=xx*3+yy;string temp=cur;swap(temp[pos],temp[ppos]);if(vis[temp])continue;path[cnt].pre=vis[cur];path[cnt].dir=i;vis[temp]=cnt++;q.push(temp);}} }//2 3 4 //1 5 x //7 6 8int main() { // freopen("input.txt","r",stdin);bfs();//預處理打表char s[5];while(scanf("%s",s)!=EOF){string str;if(s[0]=='x')str+='0';elsestr+=s[0];for(int i=0;i<8;i++){scanf("%s",s);if(s[0]=='x')str+='0';elsestr+=s[0];}if(!vis[str])//如果該狀態遍歷不到,則無解printf("unsolvable\n");else//如果該狀態能遍歷到,則直接輸出路徑即可{int k=vis[str];while(k!=-1){putchar(p[path[k].dir]);k=path[k].pre;}putchar('\n');}}return 0; }

?

總結

以上是生活随笔為你收集整理的HDU - 1043 Eight(bfs打表)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。