課程練習二-1010-Catch him

Problem Description
在美式足球中,四分衛負責指揮整隻球隊的進攻戰術和跑位,以及給接球員傳球的任務。四分衛是一隻球隊進攻組最重要的球員,而且一般身體都相對比較弱小,所以通常球隊會安排5-7名大漢來保護他,其中站在四分衛前方、排成一線的5名球員稱爲進攻鋒線,他們通常都是135公斤左右的壯漢。<br><img src=../../../data/images/2531-1.jpg><br>對防守方來說,攻擊對手的四分衛當然是最直接的限制對手進攻的方法。如果效果好,就可以在對方四分衛傳球之前將其按翻在地,稱之爲擒殺。擒殺是最好的鼓舞防守隊士氣的方法,因爲對方連傳球的機會都沒有,進攻就結束了,還必須倒退一些距離開球。兇狠的擒殺甚至能夠將對方的四分衛弄傷,從而迫使對方更換這個進攻核心。<br>在本題中,輸入給出準備擒殺四分衛的防守球員的位置、對方每個進攻鋒線球員的位置以及對方四分衛的位置,你的任務是求出這名準備擒殺的防守球員至少要移動多少步,才能夠擒殺對方四分衛。<br>假設對方進攻鋒線和四分衛在這個過程中都不會移動。只有1名防守球員,防守球員只要碰到對方四分衛就算擒殺。<br>所有的球員都是一塊連續的、不中空的2維區域。防守球員不可以從進攻鋒線的身體上穿過,也不可以從界外穿過(只能走空地)。<br>防守隊員不可以轉動身體,只能平移。防守隊員的身體所有部分向同一個方向(上、下、左、右)移動1格的過程叫做1步。<br>
 

Input
輸入包含多組數據。每組數據第一行都是兩個整數H,W(0<H,W<=100),表示整個區域的高度和寬度,H=W=0表示輸入結束。接下來有H行,每行W個字符。每個字符如果是’.’,表示這裏是空地,如果是’O’,表示是進攻鋒線隊員的身體,如果是’D’,表示是準備擒殺的防守球員的身體,如果是’Q’,表示是四分衛的身體。<br>輸入保證符合上面的條件。防守球員的身體總共不超過20格。<br><br>
 

Output
對每組數據,輸出包含擒殺所需最少步數的一行。如果不能擒殺,輸出帶’Impossible’的一行。
 

Sample Input
6 6<br>.Q....<br>QQ..OO<br>.OO..O<br>...O.O<br>OO.O..<br>....DD<br>7 7<br>.Q.....<br>QQ.OOO.<br>...O...<br>O......<br>OO..OO.<br>.O.....<br>.....DD<br>0 0<br>
 

Sample Output

Impossible<br>9<br>

思路:

bfs檢索每個防守球員到4分位的位置,取出最小的。(剛開始理解錯的思路)

實際上這題直接bfs。

感想:

這題幹翻譯真他孃的操蛋!什麼身體,亂七八糟的。

就是有幾個D(<20)那麼所有的D都要一起移動,把所有的D看成一個整體。

剛開始以爲只要 存在D可以到達Q就 ok呢,(還以爲測試數據錯了,這題出的,是出題者翻譯的不行呢?還是我理解能力有問題?)

我已無力吐槽!

剛開始代碼:(題意理解錯了)

#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<stdlib.h> #include<string.h> #include<fstream> #include<algorithm> #include<queue> using namespace std; char point[102][102]; int H, W; bool flag[102][102]; int direction[4][2] = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } }; struct position { int x, y; int ans; }; int bfs(int i,int j) { position p; p.x = i; p.y = j; p.ans = 0; flag[p.x][p.y] = true; queue<position>Q; Q.push(p); while (!Q.empty()) { position q = Q.front(); Q.pop(); if (point[q.x][q.y] == 'Q') { return q.ans; } for (int i = 0; i < 4; i++) { position p; p.x = q.x + direction[i][0]; p.y = q.y + direction[i][1]; p.ans = q.ans + 1; if (point[p.x][p.y] == 'O' || flag[p.x][p.y]) continue; if (p.ans > 20) return 0; if (p.x>=H || p.y >= W || p.x < 0 || p.y < 0) continue; Q.push(p); flag[p.x][p.y] = true; } } return 0; } int main() { freopen ("C:\\Users\\liuzhen\\Desktop\\11.txt", "r", stdin); while (1) { cin >> H >> W; if (H == 0 && W == 0) break; for (int i = 0; i < H; i++) for (int j = 0; j < W; j++) { cin >> point[i][j]; }

int cou[100]; memset(cou, 0, sizeof(cou)); int m = 0; for (int i = 0; i < H; i++) for (int j = 0; j < W; j++) { if (point[i][j] == 'D') { memset(flag, false, sizeof(flag));

cou[m++]=bfs(i, j); } }

sort(cou, cou + m); if (cou[0]!=0) cout << cou[0] << endl; else cout << "Impossible" << endl; } freopen("CON", "r", stdin); system("pause"); return 0; }

AC代碼:(需要將上面代碼中結構體改一下,用於存放所有的D;對於標記的問題,只需要標記第一個D的位置

即可(若都標記,則會出錯,自己考慮,不解釋))。

#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<stdlib.h> #include<string.h> #include<fstream> #include<algorithm> #include<queue> using namespace std; char point[102][102]; int H, W; bool flag[102][102]; int direction[4][2] = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } }; struct position { int x[21], y[21]; int ans; }; int bfs(int ax[],int ay[],int m) { position p; for (int i = 0; i < m; i++) { p.x[i] = ax[i]; p.y[i] = ay[i]; } p.ans = 0; flag[p.x[0]][p.y[0]] = true; queue<position>Q; Q.push(p); while (!Q.empty()) { position q = Q.front(); Q.pop(); for (int i = 0; i < m; i++) { if (point[q.x[i]][q.y[i]] == 'Q') { return q.ans; } } for (int i = 0; i < 4; i++) { position p; int mm = 0; for (int j = 0; j < m; j++) { p.x[j] = q.x[j] + direction[i][0]; p.y[j] = q.y[j] + direction[i][1]; p.ans = q.ans + 1; if (p.x[j] >= H || p.y[j] >= W || p.x[j] < 0 || p.y[j] < 0) { mm++; break; } else { if (point[p.x[j]][p.y[j]] == 'O' || flag[p.x[0]][p.y[0]]) { mm++; break; } } } if (mm == 0) { Q.push(p); flag[p.x[0]][p.y[0]] = true; } } } return 0; } int main() { freopen ("C:\\Users\\liuzhen\\Desktop\\11.txt", "r", stdin); while (1) { cin >> H >> W; if (H == 0 && W == 0) break; for (int i = 0; i < H; i++) for (int j = 0; j < W; j++) { cin >> point[i][j]; } int cou[100]; memset(cou, 0, sizeof(cou)); memset(flag, false, sizeof(flag)); int m = 0; int ax[21],ay[21]; for (int i = 0; i < H; i++) for (int j = 0; j < W; j++) { if (point[i][j] == 'D') { ax[m] = i; ay[m] = j; m++; } } int ans = bfs(ax,ay,m); if (ans!=0) cout << ans << endl; else cout << "Impossible" << endl; } freopen("CON", "r", stdin); system("pause"); return 0; }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章