青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

ACM___________________________

______________白白の屋
posts - 182, comments - 102, trackbacks - 0, articles - 0
<2011年4月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

常用鏈接

留言簿(24)

隨筆分類(332)

隨筆檔案(182)

FRIENDS

搜索

積分與排名

最新隨筆

最新評論

閱讀排行榜

評論排行榜

MiYu原創, 轉帖請注明 : 轉載自 ______________白白の屋

題目地址:

     http://acm.hdu.edu.cn/showproblem.php?pid=1010 

題目描述:

 代碼

Tempter of the Bone

Time Limit: 
2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 
16817    Accepted Submission(s): 4693


Problem Description
The doggie found a bone 
in an ancient maze, which fascinated him a lot. However, when he picked it up, the maze began to shake, and the doggie could feel the ground sinking. He realized that the bone was a trap, and he tried desperately to get out of this maze.

The maze was a rectangle with sizes N by M. There was a door 
in the maze. At the beginning, the door was closed and it would open at the T-th second for a short period of time (less than 1 second). Therefore the doggie had to arrive at the door on exactly the T-th second. In every second, he could move one block to one of the upper, lower, left and right neighboring blocks. Once he entered a block, the ground of this block would start to sink and disappear in the next second. He could not stay at one block for more than one second, nor could he move into a visited block. Can the poor doggie survive? Please help him.
 

Input
The input consists of multiple test cases. The first line of each test 
case contains three integers N, M, and T (1 < N, M < 70 < T < 50), which denote the sizes of the maze and the time at which the door will open, respectively. The next N lines give the maze layout, with each line containing M characters. A character is one of the following:

'X': a block of wall, which the doggie cannot enter; 
'S': the start point of the doggie; 
'D': the Door; or
'.': an empty block.

The input 
is terminated with three 0's. This test case is not to be processed.
 

Output
For each test 
case, print in one line "YES" if the doggie can survive, or "NO" otherwise.
 

Sample Input
4 4 5
S.X.
..X.
..XD
....
3 4 5
S.X.
..X.
...D
0 0 0
 

Sample Output
NO
YES 

 

 

題目分析 :

   傳說中的 搜索題中具有里程碑意義的題目........

很好,很強大. 做過過這題大概也就明白了 搜索中的 奇偶剪枝以及路徑. 加了剪枝的直接結果就是 TLE 和 46MS AC.......

剛開始做的時候,也沒明白剪枝到底有什么作用, 所以直接敲了個DFS代碼就交了, 答案很明顯....TLE.  然后就去學習PPT去了.

所謂奇偶剪枝 : 

  1. 把矩陣標記成如下形式:
  2. 0,1,0,1,0
  3. 1,0,1,0,1
  4. 0,1,0,1,0
  5. 1,0,1,0,1
  6. 很明顯,如果起點在0 而終點在1 那顯然 要經過奇數步才能從起點走到終點,依次類推,奇偶相同的偶數步,奇偶不同的奇數步
  7. 在讀入數據的時候就可以判斷,并且做剪枝,當然做的時候并不要求把整個矩陣0,1刷一遍,讀入的時候起點記為(Si,Sj) 終點記為(Di,Dj) 判斷(Si+Sj) 和 (Di+Dj) 的奇偶性就可以了
 

所謂路徑剪枝:  

    矩陣的大小是N*M 墻的數量記為wall 如果能走的路的數量 N*M - wall 小于時間T,就是說走完也不能到總的時間的,這顯然是錯誤的,可以直接跳出了.

   另外還有就是, 當DFS深度 > T 時,顯然也不用繼續找下去了. 那狗已經掛了. 

所以在經過這3次剪枝后, 時間就大大縮短了. 

 

值得一提的是!!! 這題我WA了很久, 一直找不原因,  因為數據不一定是按嚴格矩陣排列的!! 也可能都在一行!!!! 所以 無論是 gets 還是 getchar 都錯的很冤枉.

使用 cin  和 scanf ("%s") 后 AC 了, 在此感謝 AMB神牛的幫忙....... 

 

代碼如下:

 /*

MiYu原創, 轉帖請注明 : 轉載自 ______________白白の屋

Author By : MiYu

Test      : 1

Program   : HDU1010

*/


#include <iostream>

#include <ctime>

using namespace std;

typedef struct pos{

       int x,y;

       void setPos( int a = 0,int b = 0 ){ x = a; y = b; }

}POS; 

POS start,end;

const int START = 10;  //看了就知道啥意思 

const int DOOR = 20;

const int WALL = 0;

const int ROAR = 1;

int N = 0,M = 0,T = 0; //輸入的 

int maze[11][11];      //很明顯是迷宮地圖 

int d[4][2] = { { 0,1 },{ 1,0 },{ 0,-1 },{ -1,0 } };

int f = 1,roarCount = 0;  //標記是否找到路 , 記錄可以走的路的個數 

int DFS ( int x,int y,int n )

{

    if ( n == T )     //時間用完了, 走到出口沒 ? 

    {

         if ( x == end.x && y == end.y )

              f = 0;

         return 0;  

    }

    if ( f == 0 )     //已經找到路了, 不用找了  

         return 0;

    int t = T - n - abs( x-end.x ) - abs( y-end.y );   

    if ( t < 0 || t % 2 == 1 )     //不夠時間了 或 不可能走到(奇偶剪枝)

         return 0;  

    for ( int i = 0; i != 4; ++ i )

    {

          if ( maze[ x+d[i][0] ][ y+d[i][1] ] != WALL )    //先看看下一步能不能走 

          {

                     maze[x+d[i][0]][y+d[i][1]] = WALL;    //走過后就不能走了 

                     DFS ( x+d[i][0], y+d[i][1], n + 1 );  //走到下一個位置 

                     if ( f == 0 )     //已經找到路了, 不用找了  

                          return 0; 

                     maze[x+d[i][0]][y+d[i][1]] = ROAR;    //沒找到路,回溯下 

          }

    } 

    return 0;

}

void init()  //在主函數一堆, 難看, 放外面了, 不解釋 

{

     memset ( maze, 0, sizeof ( maze ) );

     f = 1, roarCount = 0;

     for ( int i = 1; i <= N; ++ i )

     {

           char ch;

           for ( int j = 1; j <= M ; ++ j )

           {           

                 cin >> ch;

                 switch ( ch )

                 {

                         case 'S':  maze[i][j] = START; start.setPos ( i,j ); break;

                         case '.':  maze[i][j] = ROAR;  roarCount ++; break;

                         case 'X':  maze[i][j] = WALL;  break;              

                         case 'D':  maze[i][j] = DOOR;  end.setPos ( i,j ); roarCount ++; break;

                 }

           } 

     }      

}

int main ()

{

    while ( cin >> N >> M >> T, N + M + T )

    {

           init ();

           if ( roarCount >= T )      //當然要保證能走的路比開門的時間要多 

           {

                maze[start.x][start.y] = WALL;

                DFS( start.x, start.y, 0 );

           }  

           puts ( f == 1 ? "NO" : "YES" );

    }

    return 0;

}

另外附上一網友詳細解釋:

 


  1. 1010 temp of the bone
  2. sample input:
  3. 4 4 5
  4. S.X.
  5. ..X.
  6. ..XD
  7. ....
  8. 問題:
  9. (1):
  10. 在發現當前節點無法到達時,這點彈出棧,并且把這點的標記重新刷為'.'
  11. (2):
  12. 如何在dfs中既要保證到達又要使時間正好呢?? 在函數中通過這種形式實現:
  13. dfs(int si,int sj,int cnt) 就是用cnt來記錄當時的時間,并且在
  14. if( si==di && sj==dj && cnt==t )
  15.     {
  16.         escape = 1;
  17.         return;
  18.     }
  19. 的時候 即當前點到達了終點并且時間恰好等于題目所給限制時間時,跳出
  20. 并且escape標記為真
  21. (3):
  22. 如何讓一個點有順序地遍歷它四周地能到達的點呢??
  23. 聰明并且簡短的方法是設施一個dir[4][2] 數組 控制方向
  24. 并且設置它的值為dir[4][2]={{0,-1},{0,1},{1,0},{-1,0}};
  25. 遍歷的時候用for(i:0->4)就非常方便了
  26. (4):
  27. 千萬要注意的是節點越界的情況, dfs(int si,int sj,int cnt)的時候一定要把 si, sj 控制在給你的矩陣內 在后面會提到一個我的列子 就是因為訪問了[0, -1]的位置導致了其
  28. 他數據被更改
  29. (5):
  30. 讀入矩陣的時候,可以采用for(i = 1; i <= N; i++)
  31.                for(j = 1; j <= M; j++)
  32.                 scanf("%c", &map[i][j]);       
  33. 的方法,好處在于可以控制和計算每一個讀入的數據,壞處是調試的時候對矩陣的觀察不太方便,而且好像還會有錯誤,在2102"A計劃"用這種方法讀入數據時好像就會wa,
  34. 另一種方法是for(i = 0; i < N; i++) gets(map[i]);
  35. 這樣讀入的數據在調試觀察的時候十分方便 gets()讀入的默認為字符串,在vc調試的時候是顯式的 可以直接觀察矩陣 缺點是對矩陣中各個數據的計算和控制無法實現,需要讀完后再遍歷一遍
  36. (6)
  37. 能用bfs還是盡量用bfs 我不會bfs.... dfs的遞歸在調試的時候不是很方便,而且bfs要比dfs快,調試也要方便,因為它沒有遞歸
  38. (7)
  39. 關于剪枝,沒有剪枝的搜索不太可能,這題老劉上課的時候講過兩個剪枝,一個是奇偶剪枝,一個是路徑剪枝
  40. 奇偶剪枝:
  41. 把矩陣標記成如下形式:
  42. 0,1,0,1,0
  43. 1,0,1,0,1
  44. 0,1,0,1,0
  45. 1,0,1,0,1
  46. 很明顯,如果起點在0 而終點在1 那顯然 要經過奇數步才能從起點走到終點,依次類推,奇偶相同的偶數步,奇偶不同的奇數步
  47. 在讀入數據的時候就可以判斷,并且做剪枝,當然做的時候并不要求把整個矩陣0,1刷一遍,讀入的時候起點記為(Si,Sj) 終點記為(Di,Dj) 判斷(Si+Sj) 和 (Di+Dj) 的奇偶性就可以了
  48. 路徑剪枝:
  49. 矩陣的大小是N*M 墻的數量記為wall 如果能走的路的數量 N*M - wall 小于時間T,就是說走完也不能到總的時間的,這顯然是錯誤的,可以直接跳出了
  50. 課件里面給過這題的標程,在dfs的過程中有個沒提到的剪枝,就是記錄當前點到終點的最短路,如果小于剩余的時間的話,就跳出
  51. 這個剪枝我覺得更科學,它畢竟是動態的么,標程里面是這么寫的:
  52. temp = (t-cnt) - abs(si-di) - abs(sj-dj);
  53. if( temp<0 || temp&1 ) return;
  54. 其中求當前點到終點的最短路是這樣 abs(si-di) - abs(sj-dj) 這個就比較粗糙了 明顯沒有考慮到碰到墻要拐彎的情況
  55. 那求最短路有沒有什么好辦法呢?
  56. 我曾經想到過用 Dijkstraq求最短路的 ,明顯大才小用,在論壇里看到一個方法覺得可以用在這里
  57. 給定下例:
  58. S.X.
  59. ..X.
  60. ..XD
  61. ....
  62. 每個點到終點的最短路是不是這樣呢:
  63. S6X2
  64. 65X1
  65. 54XD
  66. 4321
  67. 這怎么求呢??從終點開始遍歷整個數組,終點是0,它周圍的點都+1,墻就不計數,依次類推,就能求得這個矩陣的一個最短時間矩陣,在dfs的時候比較當前點到終點的最短路,如果大于剩余時間的話就跳出
  68. 這個方法的預處理還是非常快的,我沒有用過,但是感覺會非常有用處.
  69. (8)
  70. 在做這題的時候,我碰到過一個神奇的事情,在程序運行至下面代碼時
  71. if( map[ si+dir[i][0] ][ sj+dir[i][1] ] != 'X')           
  72.     map[ si+dir[i][0] ][ sj+dir[i][1] ] = 'X';
  73. T被改變了!! 這絲毫和T沒有關系啊,怎么改變T的值呢??
  74. 原來在起點map[0][0]進入時,我沒有注意到map[ si+dir[i][0] ][ sj+dir[i][1] ] 實際做的是map[0][-1] = 'X'; 很危險的一個賦值,書本上千萬次強調的東西讓我碰上了,這個地方我找了很久,因此我覺得有必要單獨列出來提醒自己
  75. //////////////////////////////////////////////////////////////////////////////////////////////////////////////
  76. 下面我把一個帶注釋的標程貼一下,不是我寫的注釋
  77. //zju 2110 Tempter of the Bone
  78. #include <stdio.h>
  79. #include <iostream>
  80. #include <string.h>
  81. #include <stdlib.h>
  82. using namespace std;
  83. //迷宮地圖
  84. //X: 墻壁,小狗不能進入
  85. //S: 小狗所處的位置
  86. //D: 迷宮的門
  87. //. : 空的方格
  88. char map[9][9];
  89. int n,m,t,di,dj; //(di,dj):門的位置
  90. bool escape;
  91. int dir[4][2]={{0,-1},{0,1},{1,0},{-1,0}}; //分別表示下、上、左、右四個方向
  92. void dfs(int si,int sj,int cnt)  //表示起始位置為(si,sj),要求在第cnt秒達到門的位置
  93. {
  94.     int i,temp;
  95.     if( si>n || sj>m || si<=0 || sj<=0 ) return;
  96.    
  97.     if( si==di && sj==dj && cnt==t )
  98.     {
  99.         escape = 1;
  100.         return;
  101.     }
  102.    
  103.     //abs(x-ex) + abs(y - ey)表示現在所在的格子到目標格子的距離(不能走對角線)
  104.     //t-cnt是實際還需要的步數,將他們做差
  105.     //如果temp < 0或者temp為奇數,那就不可能到達!
  106.     temp = (t-cnt) - abs(si-di) - abs(sj-dj);
  107.    
  108.     if( temp<0 || temp&1 ) return;
  109.    
  110.     for( i=0; i<4; i++ )
  111.     {
  112.         if( map[ si+dir[i][0] ][ sj+dir[i][1] ] != 'X')
  113.         {
  114.             map[ si+dir[i][0] ][ sj+dir[i][1] ] = 'X';
  115.                
  116.                 dfs(si+dir[i][0], sj+dir[i][1], cnt+1);
  117.            
  118.             if(escape) return;
  119.            
  120.             map[ si+dir[i][0] ][ sj+dir[i][1] ] = '.';
  121.         }
  122.     }
  123.    
  124.     return;
  125. }
  126. int main()
  127. {
  128.     int i,j,si,sj;
  129.    
  130.     while( cin >> n >> m >> t)
  131.     {
  132.         if( n==0 && m==0 && t==0 )
  133.             break;
  134.    
  135.         int wall = 0;
  136.         for( i=1; i<=n; i++ )
  137.             for( j=1; j<=m; j++ )
  138.             {
  139.                 cin >> map[i][j];
  140.                 if(map[i][j]=='S') { si=i; sj=j; }
  141.                 else if( map[i][j]=='D' ) { di=i; dj=j; }
  142.                 else if( map[i][j]=='X' ) wall++;
  143.             }
  144.            
  145.             if( n*m-wall <= t )
  146.             {
  147.                 cout << "NO" << endl;
  148.                 continue;
  149.             }
  150.            
  151.             escape = 0;
  152.             map[si][sj] = 'X';
  153.            
  154.             dfs( si, sj, 0 );
  155.            
  156.             if( escape ) cout << "YES" << endl;
  157.             else cout << "NO" << endl;
  158.     }
  159.    
  160.     return 0;
  161. }
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            男人插女人欧美| 国产模特精品视频久久久久| 欧美日韩中字| 亚洲日本免费电影| 9久草视频在线视频精品| 欧美激情综合五月色丁香| 在线播放一区| 亚洲女人天堂成人av在线| 亚洲欧美综合v| 嫩草国产精品入口| 久久影视精品| 91久久综合| 欧美国产视频日韩| 久久国内精品视频| 免费看黄裸体一级大秀欧美| 一区二区三区 在线观看视| 久久aⅴ国产欧美74aaa| 亚洲国产欧美一区二区三区同亚洲 | 免费欧美在线| 欧美美女喷水视频| 久久久久久亚洲精品杨幂换脸| 欧美电影免费网站| 免费毛片一区二区三区久久久| 亚洲欧美一区二区三区久久| 在线欧美日韩国产| 一本色道久久综合亚洲精品小说| 在线观看精品| 国产精品99久久久久久www| 欧美成年人在线观看| 久久一区国产| 国产午夜精品久久久久久久| 日韩视频一区二区三区在线播放免费观看 | 久久久99久久精品女同性| 久久影院午夜片一区| 欧美亚洲免费高清在线观看| 欧美日韩免费在线视频| 91久久夜色精品国产九色| 久久天天躁狠狠躁夜夜av| 老司机午夜精品视频在线观看| 国产偷自视频区视频一区二区| 久久国产精品网站| 欧美黄色大片网站| 欧美一区二区三区在线播放| 久久国产精品电影| 久久久久久午夜| 国产视频久久久久| 亚洲已满18点击进入久久| 99视频精品全部免费在线| 亚洲精选一区| 欧美日韩视频免费播放| 一二三四社区欧美黄| 久久精品视频免费| 日韩一区二区高清| 国产亚洲激情| 欧美日韩免费观看一区二区三区| 亚洲欧美日韩精品久久亚洲区| 欧美风情在线观看| 亚洲一区在线免费观看| 在线看片成人| 国产伦精品一区二区三区高清版| 欧美在线精品免播放器视频| aa级大片欧美| 亚洲国产三级网| 久久综合伊人| 性欧美大战久久久久久久久| 国产精品网站在线播放| 欧美 日韩 国产在线| 久久久久久久综合狠狠综合| 亚洲欧美日本伦理| 一本大道久久a久久综合婷婷 | 久久成人免费电影| 亚洲午夜激情| 亚洲桃花岛网站| 亚洲精品免费观看| 欧美福利网址| 欧美二区不卡| 日韩视频免费在线| 一区二区日韩精品| 亚洲私人影院| 久久xxxx| 99视频在线精品国自产拍免费观看 | 亚洲精品国产精品国产自| 欧美日韩调教| 国产伦一区二区三区色一情| 国产精品久久久久久福利一牛影视| 欧美日韩精品免费| 久久精品男女| 欧美日韩高清不卡| 久久久久一本一区二区青青蜜月| 午夜免费电影一区在线观看| 午夜精品免费视频| 玖玖玖国产精品| 欧美日韩中文字幕日韩欧美| 国产欧美韩日| 亚洲精品影院在线观看| 亚洲视频免费观看| 一本色道久久综合亚洲二区三区| 一本大道久久a久久精二百| 午夜精品久久久久久久久久久久 | 亚洲色在线视频| 性欧美办公室18xxxxhd| 欧美高清视频一二三区| 国产午夜精品全部视频在线播放| 亚洲高清激情| 亚洲欧美日韩中文在线制服| 嫩草成人www欧美| 国产婷婷成人久久av免费高清| 亚洲精品老司机| 欧美成人精品h版在线观看| 亚洲一区二区高清| 欧美一级二级三级蜜桃| 欧美成人日韩| 亚洲国产精品va在线观看黑人| 亚洲欧美视频在线| 日韩视频在线播放| 噜噜噜噜噜久久久久久91| 一区二区在线看| 欧美与欧洲交xxxx免费观看 | 久久精品国产欧美激情| 91久久综合亚洲鲁鲁五月天| 欧美一区2区三区4区公司二百| 国产精品久久久久久模特| 亚洲一区二区三区777| 在线视频欧美日韩| 国产精品日日做人人爱| 久久精品国产精品亚洲综合| 性8sex亚洲区入口| 国产真实乱偷精品视频免| 久久亚洲国产成人| 久热re这里精品视频在线6| 亚洲国产精品www| 夜夜狂射影院欧美极品| 国产精品一区一区| 久久婷婷蜜乳一本欲蜜臀| 狼人天天伊人久久| 亚洲一区三区电影在线观看| 午夜精品一区二区三区在线播放 | 欧美精品在线免费播放| 午夜精品在线| 欧美剧在线免费观看网站| 国产日韩在线不卡| 亚洲国产精品小视频| 国产美女一区二区| 亚洲欧洲免费视频| 国产一区二区精品丝袜| 亚洲国产裸拍裸体视频在线观看乱了| 欧美成人精品高清在线播放| 亚洲综合电影| 久久精品国产一区二区三区| 欧美女同在线视频| 欧美wwwwww| 国产九九精品| 亚洲欧洲日产国产综合网| 狠狠色丁香久久婷婷综合_中| 亚洲国产日韩一级| 亚洲福利小视频| 亚洲国产综合视频在线观看| 国内精品免费在线观看| 91久久精品美女高潮| 国产麻豆综合| 久久天天狠狠| 欧美亚男人的天堂| 亚洲高清不卡| 亚洲人成亚洲人成在线观看| 国产亚洲精品久久久久动| 亚洲日本国产| 亚洲日本免费| 在线一区观看| 日韩小视频在线观看专区| 亚洲欧美在线网| 午夜精品福利在线| 国产精品久久久久婷婷| 久久久久国产精品一区| 国产精品影院在线观看| 久久九九免费| 国内精品伊人久久久久av影院| 午夜久久资源| 久久爱www| 国产精品毛片| 亚洲一区欧美| 亚洲精选一区| 欧美精品在线免费| 亚洲欧美日韩高清| 久久久久久亚洲精品中文字幕| 亚洲欧美国产制服动漫| 1024成人网色www| 午夜精品久久久久| 亚洲欧美综合一区| 亚洲激情国产| 亚洲欧美激情诱惑| 国产日韩欧美在线视频观看| 先锋a资源在线看亚洲| 久久丁香综合五月国产三级网站| 在线播放日韩专区| 久久精品视频网| 牛夜精品久久久久久久99黑人| 一本色道久久综合一区| 午夜一区在线| 日韩一级片网址| 久久久久久欧美|