生活随笔
收集整理的這篇文章主要介紹了
hdu1010 Tempter of the Bone
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
轉載自:http://acm.hdu.edu.cn/forum/read.php?tid=6158sample input:4 4 5S.X...X...XD.... 問題:(1):在發現當前節點無法到達時,這點彈出棧,并且把這點的標記重新刷為'.' (2):如何在dfs中既要保證到達又要使時間正好呢?? 在函數中通過這種形式實現: dfs(int si,int sj,int cnt) 就是用cnt來記錄當時的時間,并且在 if( si==di && sj==dj && cnt==t )? ? {? ? ? ? escape = 1;? ? ? ? return;? ? } 的時候 即當前點到達了終點并且時間恰好等于題目所給限制時間時,跳出并且escape標記為真 (3):如何讓一個點有順序地遍歷它四周地能到達的點呢??聰明并且簡短的方法是設施一個dir[4][2] 數組 控制方向并且設置它的值為dir[4][2]={{0,-1},{0,1},{1,0},{-1,0}}; 遍歷的時候用for(i:0->4)就非常方便了 (4):千萬要注意的是節點越界的情況, dfs(int si,int sj,int cnt)的時候一定要把 si, sj 控制在給你的矩陣內 在后面會提到一個我的列子 就是因為訪問了[0, -1]的位置導致了其 他數據被更改 (5):讀入矩陣的時候,可以采用for(i = 1; i <= N; i++)? ? ? ? ? ?? ? for(j = 1; j <= M; j++)? ? ? ? ? ? ? ? scanf("%c", &map[i][j]);? ? ? ? 的方法,好處在于可以控制和計算每一個讀入的數據,壞處是調試的時候對矩陣的觀察不太方便,而且好像還會有錯誤,在2102"A計劃"用這種方法讀入數據時好像就會wa, 另一種方法是for(i = 0; i < N; i++) gets(map[i]);這樣讀入的數據在調試觀察的時候十分方便 gets()讀入的默認為字符串,在vc調試的時候是顯式的 可以直接觀察矩陣 缺點是對矩陣中各個數據的計算和控制無法實現,需要讀完后再遍歷一遍 (6)能用bfs還是盡量用bfs 我不會bfs.... dfs的遞歸在調試的時候不是很方便,而且bfs要比dfs快,調試也要方便,因為它沒有遞歸 (7)關于剪枝,沒有剪枝的搜索不太可能,這題老劉上課的時候講過兩個剪枝,一個是奇偶剪枝,一個是路徑剪枝 奇偶剪枝:把矩陣標記成如下形式:0,1,0,1,01,0,1,0,10,1,0,1,01,0,1,0,1很明顯,如果起點在0 而終點在1 那顯然 要經過奇數步才能從起點走到終點,依次類推,奇偶相同的偶數步,奇偶不同的奇數步在讀入數據的時候就可以判斷,并且做剪枝,當然做的時候并不要求把整個矩陣0,1刷一遍,讀入的時候起點記為(Si,Sj) 終點記為(Di,Dj) 判斷(Si+Sj) 和 (Di+Dj) 的奇偶性就可以了 路徑剪枝:矩陣的大小是N*M 墻的數量記為wall 如果能走的路的數量 N*M - wall 小于時間T,就是說走完也不能到總的時間的,這顯然是錯誤的,可以直接跳出了 課件里面給過這題的標程,在dfs的過程中有個沒提到的剪枝,就是記錄當前點到終點的最短路,如果小于剩余的時間的話,就跳出這個剪枝我覺得更科學,它畢竟是動態的么,標程里面是這么寫的:temp = (t-cnt) - abs(si-di) - abs(sj-dj);if( temp<0 || temp&1 ) return; 其中求當前點到終點的最短路是這樣 abs(si-di) - abs(sj-dj) 這個就比較粗糙了 明顯沒有考慮到碰到墻要拐彎的情況那求最短路有沒有什么好辦法呢? 我曾經想到過用 Dijkstraq求最短路的 ,明顯大才小用,在論壇里看到一個方法覺得可以用在這里給定下例: S.X...X...XD.... 每個點到終點的最短路是不是這樣呢: S6X265X154XD4321 這怎么求呢??從終點開始遍歷整個數組,終點是0,它周圍的點都+1,墻就不計數,依次類推,就能求得這個矩陣的一個最短時間矩陣,在dfs的時候比較當前點到終點的最短路,如果大于剩余時間的話就跳出 這個方法的預處理還是非常快的,我沒有用過,但是感覺會非常有用處. (8)在做這題的時候,我碰到過一個神奇的事情,在程序運行至下面代碼時 if( map[ si+dir[i][0] ][ sj+dir[i][1] ] != 'X')? ? ? ? ? ?? ? map[ si+dir[i][0] ][ sj+dir[i][1] ] = 'X'; T被改變了!! 這絲毫和T沒有關系啊,怎么改變T的值呢?? 原來在起點map[0][0]進入時,我沒有注意到map[ si+dir[i][0] ][ sj+dir[i][1] ] 實際做的是map[0][-1] = 'X'; 很危險的一個賦值,書本上千萬次強調的東西讓我碰上了,這個地方我找了很久,因此我覺得有必要單獨列出來提醒自己 //下面我把一個帶注釋的標程貼一下,不是我寫的注釋 //zju 2110 Tempter of the Bone#include <stdio.h>#include <iostream>#include <string.h>#include <stdlib.h> using namespace std; //迷宮地圖//X: 墻壁,小狗不能進入//S: 小狗所處的位置//D: 迷宮的門//. : 空的方格char map[9][9];int n,m,t,di,dj; //(di,dj):門的位置bool escape;int dir[4][2]={{0,-1},{0,1},{1,0},{-1,0}}; //分別表示下、上、左、右四個方向 void dfs(int si,int sj,int cnt)? //表示起始位置為(si,sj),要求在第cnt秒達到門的位置{? ? int i,temp;? ? if( si>n || sj>m || si<=0 || sj<=0 ) return;? ?? ? if( si==di && sj==dj && cnt==t )? ? {? ? ? ? escape = 1;? ? ? ? return;? ? }? ?? ? //abs(x-ex) + abs(y - ey)表示現在所在的格子到目標格子的距離(不能走對角線)? ? //t-cnt是實際還需要的步數,將他們做差? ? //如果temp < 0或者temp為奇數,那就不可能到達!? ? temp = (t-cnt) - abs(si-di) - abs(sj-dj);? ?? ? if( temp<0 || temp&1 ) return;? ?? ? for( i=0; i<4; i++ )? ? {? ? ? ? if( map[ si+dir[i][0] ][ sj+dir[i][1] ] != 'X')? ? ? ? {? ? ? ? ? ? map[ si+dir[i][0] ][ sj+dir[i][1] ] = 'X';? ? ? ? ? ? ? ?? ? ? ? ? ? ? ? dfs(si+dir[i][0], sj+dir[i][1], cnt+1);? ? ? ? ? ?? ? ? ? ? ? if(escape) return;? ? ? ? ? ?? ? ? ? ? ? map[ si+dir[i][0] ][ sj+dir[i][1] ] = '.';? ? ? ? }? ? }? ?? ? return;} int main(){? ? int i,j,si,sj;? ?? ? while( cin >> n >> m >> t)? ? {? ? ? ? if( n==0 && m==0 && t==0 )? ? ? ? ? ? break;? ?? ? ? ? int wall = 0;? ? ? ? for( i=1; i<=n; i++ )? ? ? ? ? ? for( j=1; j<=m; j++ )? ? ? ? ? ? {? ? ? ? ? ? ? ? cin >> map[i][j];? ? ? ? ? ? ? ? if(map[i][j]=='S') { si=i; sj=j; }? ? ? ? ? ? ? ? else if( map[i][j]=='D' ) { di=i; dj=j; }? ? ? ? ? ? ? ? else if( map[i][j]=='X' ) wall++;? ? ? ? ? ? }? ? ? ? ? ?? ? ? ? ? ? if( n*m-wall <= t )? ? ? ? ? ? {? ? ? ? ? ? ? ? cout << "NO" << endl;? ? ? ? ? ? ? ? continue;? ? ? ? ? ? }? ? ? ? ? ?? ? ? ? ? ? escape = 0;? ? ? ? ? ? map[si][sj] = 'X';? ? ? ? ? ?? ? ? ? ? ? dfs( si, sj, 0 );? ? ? ? ? ?? ? ? ? ? ? if( escape ) cout << "YES" << endl;? ? ? ? ? ? else cout << "NO" << endl;? ? }? ?? ? return 0;}
轉載于:https://www.cnblogs.com/duan-to-success/p/3854988.html
總結
以上是生活随笔為你收集整理的hdu1010 Tempter of the Bone的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。