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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

(最优解法)46行代码AC_HDU1242 Rescue(DFS解法+BFS解法)

發(fā)布時間:2024/2/28 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 (最优解法)46行代码AC_HDU1242 Rescue(DFS解法+BFS解法) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

勵志用少的代碼做高效表達


Problem Description

Angel was caught by the MOLIGPY! He was put in prison by Moligpy. The prison is described as a N * M (N, M <= 200) matrix. There are WALLs, ROADs, and GUARDs in the prison.
Angel’s friends want to save Angel. Their task is: approach Angel. We assume that “approach Angel” is to get to the position where Angel stays. When there’s a guard in the grid, we must kill him (or her?) to move into the grid. We assume that we moving up, down, right, left takes us 1 unit time, and killing a guard takes 1 unit time, too. And we are strong enough to kill all the guards.
You have to calculate the minimal time to approach Angel. (We can move only UP, DOWN, LEFT and RIGHT, to the neighbor grid within bound, of course.)

Input

First line contains two integers stand for N and M.
Then N lines follows, every line has M characters. “.” stands for road, “a” stands for Angel, and “r” stands for each of Angel’s friend.
Process to the end of the file.

Output

For each test case, your program should output a single integer, standing for the minimal time needed. If such a number does no exist, you should output a line containing “Poor ANGEL has to stay in the prison all his life.”


題目鏈接——>HDU-1242


分析與思考

題意:天使被魔鬼抓走了,他的一群朋友(是一群!!!)準備救他, 有可能碰到守衛(wèi),要想通過需要步數(shù)+2。求天使與其朋友之間最短步數(shù)。

如果救不出來,則需要輸出:“Poor ANGEL has to stay in the prison all his life.”

考慮到該死的天使有一群朋友, 因此我們需要將起點與終點互換,起點標記為天使的位置(因為天使只有一個),找到離他最近的朋友輸出即可。

可選用的算法有DFS或BFS。 我使用的是DFS求解。 BFS解法后續(xù)更新。 請持續(xù)關(guān)注~。


二更:

更新了BFS的解法, 其中DFS解法耗時78MS, BFS解法耗時15MS, 筆者查看了網(wǎng)上大部分的代碼,目前來講的最優(yōu)解,應(yīng)該就是基于BFS的算法了。

注意:在用BFS解題時,我們往往會覺得第一個入隊的’r’一定代表最短路(老慣性思維了,該死), 但本題的特殊點在于有’x’守衛(wèi),遇守衛(wèi)需+2步,因此在迭代時可能得不到最優(yōu)解,如這組數(shù)據(jù):

2 5
axxxr

正確答案是:6
錯誤答案是:7

雖然不考慮這種特殊情況的代碼,提交也可以AC。
但作為一個處女座程序猿,就想把代碼搞到完美~
解決辦法是:定義一個Min變量,有多條路時保存最小值即可。

網(wǎng)上很多的博客都忽略了這一點,大家在參考時一定要注意。 代碼二展示了正確的寬搜解法。

后續(xù)更新DFS+BFS原理講解, 請持續(xù)關(guān)注哦~


總結(jié):本題坑點較多, 需仔細理解題意才能保證不錯。


代碼1_DFS解法

#include<bits/stdc++.h> using namespace std; char a[210][210]; //迷宮地圖 int vis[210][210]; //標記地圖中某點是否走過 int n, m; //迷宮的行列大小 int startx, starty; //迷宮起點坐標 int Min = 999999999; //所用最小步數(shù) int Next[4][2] = { //方向數(shù)組 {1, 0}, //向上{-1, 0}, //向下 {0, 1}, //向右 {0, -1}}; //向左void dfs(int x, int y, int step) {//邊界條件:找到終點,更新最小值if(a[x][y] == 'r') { Min = min(step, Min);return;} //若不是終點,判斷下一步是否為障礙物,是否越界,是否已經(jīng)走過,若無,則走 if(a[x][y]=='.' || a[x][y]=='x' || a[x][y]=='a' ) { //1、判斷是否是障礙物 for(int i = 0; i < 4; i++) {int t1 = x + Next[i][0];int t2 = y + Next[i][1];if(t1<0 || t1>=n || t2<0 || t2>=m) continue; //2、是否越界if(!vis[t1][t2]) { //3、是否已經(jīng)走過 vis[t1][t2] = 1;if(a[x][y]=='x') dfs(t1, t2, step+2);else dfs(t1, t2, step+1);vis[t1][t2] = 0;}} } } int main() {ios::sync_with_stdio(false); while(cin>>n>>m) {Min = 999999999;memset(vis, 0, sizeof(vis));for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) {cin>>a[i][j];if(a[i][j] == 'a') { startx=i, starty=j; } //由于朋友有多個,因此記錄天使位置,找朋友 }dfs(startx, starty, 0);if(Min == 999999999) cout << "Poor ANGEL has to stay in the prison all his life." << endl; else cout << Min << endl;} return 0; }

代碼2_BFS解法

#include<iostream> #include<cstring> #define Max 40100 using namespace std;struct List{int x; //橫坐標int y; //縱坐標int sum; //總步數(shù) };char a[210][210]; int vis[210][210];int Next[4][2] = {{1, 0},{-1, 0},{0,1},{0,-1}};int main() {ios::sync_with_stdio(false); int n, m; while(cin>>n>>m) {//初始化與定義變量 memset(vis, 0, sizeof(vis)); //每次循環(huán)vis數(shù)組都需初始化 int startx, starty; //起點的x、y坐標int Min = 999999999; //最后的輸出結(jié)果 bool flag = false; //終止循環(huán)的標記 //輸入 for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) {cin>>a[i][j];if(a[i][j] == 'a') startx=i, starty=j;} //隊列初始化int head=0, tail=0; //頭結(jié)點,尾結(jié)點 List l[Max];l[tail].x = startx;l[tail].y = starty;l[tail].sum = 0;tail++;vis[startx][starty] = 1;flag = 0; //標記是否到達目標點 //當(dāng)目標不為空時循環(huán) while(head < tail) { //如果尾指針小于等于頭指針,代表隊列中無元素,返回 for(int i = 0; i < 4; i++) {int tx = l[head].x + Next[i][0];int ty = l[head].y + Next[i][1]; //終止本次循環(huán)的三種條件: 越界、該點是障礙物、已經(jīng)被搜索過。 //1、若越界則返回 if(tx<0 || tx>=n || ty<1 || ty>=m) continue;//2、若沒被搜索過且該點不是障礙物,則: if(!vis[tx][ty]) if(a[tx][ty] != '#') {vis[tx][ty]=1;l[tail].x = tx;l[tail].y = ty;//如果是x,則走兩步 if(a[tx][ty] == 'x') l[tail].sum = l[head].sum+2; else l[tail].sum=l[head].sum+1;tail++; //每次循環(huán)后,tail都需自加 }if(a[tx][ty]=='r') //若等于r,則與Min比較,取較小值。 Min = min(l[tail-1].sum, Min);}head++; //每次循環(huán)都要丟棄頭部元素 }//輸出 if(Min == 999999999) cout << "Poor ANGEL has to stay in the prison all his life." << endl;else cout << Min << endl;} return 0; }

這世界就是,一些人總在晝夜不停的努力,而另外一些人,起床就發(fā)現(xiàn)世界已經(jīng)變了。

總結(jié)

以上是生活随笔為你收集整理的(最优解法)46行代码AC_HDU1242 Rescue(DFS解法+BFS解法)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。