1月 D - 逃離迷宮 HDU - 1728-復雜dfs的剪枝
阿新 • • 發佈:2019-01-22
pri 出發 col else 數據 手動 測試數據 while 包含
給定一個m × n (m行, n列)的迷宮,迷宮中有兩個位置,gloria想從迷宮的一個位置走到另外一個位置,當然迷宮中有些地方是空地,gloria可以穿越,有些地方是障礙,她必須繞行,從迷宮的一個位置,只能走到與它相鄰的4個位置中,當然在行走過程中,gloria不能走到迷宮外面去。令人頭痛的是,gloria是個沒什麽方向感的人,因此,她在行走過程中,不能轉太多彎了,否則她會暈倒的。我們假定給定的兩個位置都是空地,初始時,gloria所面向的方向未定,她可以選擇4個方向的任何一個出發,而不算成一次轉彎。gloria能從一個位置走到另外一個位置嗎? Input 第1行為一個整數t (1 ≤ t ≤ 100),表示測試數據的個數,接下來為t組測試數據,每組測試數據中, 第1行為兩個整數m, n (1 ≤ m, n ≤ 100),分別表示迷宮的行數和列數,接下來m行,每行包括n個字符,其中字符‘.‘表示該位置為空地,字符‘*‘表示該位置為障礙,輸入數據中只有這兩種字符,每組測試數據的最後一行為5個整數k, x 1, y 1, x 2, y 2 (1 ≤ k ≤ 10, 1 ≤ x 1, x 2 ≤ n, 1 ≤ y 1, y 2 ≤ m),其中k表示gloria最多能轉的彎數,(x 1, y 1), (x 2, y 2)表示兩個位置,其中x 1,x 2對應列,y 1, y 2對應行。 Output 每組測試數據對應為一行,若gloria能從一個位置走到另外一個位置,輸出“yes”,否則輸出“no”。 Sample Input2 5 5 ...** *.**. ..... ..... *.... 1 1 1 1 3 5 5 ...** *.**. ..... ..... *.... 2 1 1 1 3 Sample Output no yes
用dfs遍歷走的情況,看可不可以到終點,需要指出的是,在同一個可能面朝的方向不同,需要儲存方向這個參數
於是就遍歷嘛,上下左右都走一遍,其實我寫的時候就知道一定會超時的,但就不想剪枝(小聲逼逼
於是就tle了 (手動托臉
剪枝 :如果走了走過的格子,此時可轉彎數還少,情況就一定被走過的包含了,考慮了方向:
//turn是剩的可轉的彎數,dic是方向參數 if(cnt_t[y][x][dic]<=turn)cnt_t[y][x][dic]=turn; else return false;
這次過了,用時200ms
但總覺得哪裏不對
就算方向不同,turn數多的話turn一下就走那個方向了,所以方向並不重要,如果turn小的話直接剪掉就好了
//就像這樣... if(cnt_t[y][x]<=turn)cnt_t[y][x]=turn; else return false;
可等是因為如果之前走過而沒到終點的話,不如換個方向再試試
進一步剪了後只用15ms;
ac代碼:
#include<cstdio> #include<cstring> #define N 1 #define E 2 #define S 3 #define W 4 using namespace std; int x1,x2,y1,y2,m,n,turns,flag=0,cnt_t[110][110]; char pic[110][110]; bool dfs(int y,int x,int dic,int turn){ if(cnt_t[y][x]<=turn)cnt_t[y][x]=turn; else return false; if(flag)return true; if(turn<0) return false; if(x<1||y<1||x>n||y>m||pic[y][x]==‘*‘)return false;//printf("here %d %d\n",x,y); if(x==x2&&y==y2){flag=1; return true;} if(dic==N){ dfs(y+1,x,N,turn); dfs(y,x-1,W,turn-1); dfs(y,x+1,E,turn-1); } else if(dic==E){ dfs(y,x+1,E,turn); dfs(y+1,x,N,turn-1); dfs(y-1,x,S,turn-1); } else if(dic==S){ dfs(y-1,x,S,turn); dfs(y,x-1,W,turn-1); dfs(y,x+1,E,turn-1); } else if(dic==W){ dfs(y,x-1,W,turn); dfs(y+1,x,N,turn-1); dfs(y-1,x,S,turn-1); } return true; } int main(){ int t; scanf("%d",&t) ; while(t--){ memset(cnt_t,0,sizeof(cnt_t)); flag=0; scanf("%d%d",&m,&n); for(int i=1;i<=m;i++) scanf("%s",pic[i]+1); scanf("%d%d%d%d%d",&turns,&x1,&y1,&x2,&y2); dfs(y1,x1,N,turns); dfs(y1,x1,E,turns); dfs(y1,x1,S,turns); dfs(y1,x1,W,turns); if(flag)printf("yes\n"); else printf("no\n"); } return 0; }
1月 D - 逃離迷宮 HDU - 1728-復雜dfs的剪枝