WIKIOI-1337 銀行裏的迷宮
題目描述 Description
楚楚每一次都在你的幫助下過了一關又一關(比如他開宴會)。這一次,你的才華讓楚楚被劫住了!(好心辦了壞事啊,下次不理他了
=_=)
歹徒: hehe~
楚楚:(冷汗ing)幹啥^_^!(PS:現在還笑得出來!!!)
歹徒:搶劫的說~
楚楚:你們想幹啥!!(PS:不是告訴你了,是搶劫~)
歹徒:這裏是銀行的陷阱,也就是一個迷宮……你要帶我們離開這裏……否則……
楚楚:(想:那你是咋抓到我的,鬱悶)好吧……
楚楚認為生命還是最重要的……(大不了出去以後找警察……)
於是,他認命了……
他從歹徒口中得知這是一個方形的迷宮(歹徒老大:你還要啥形狀的,跟我說一聲!),他們的位置是[1,1],要走到[n,m],長是n,寬是
m,這是一個很大的迷宮,裏麵有陷阱(小明:能不能踩進去的,說!楚楚:當然不能,不過可以用輕功,多花一秒蓄力~用輕功走過的陷阱會石
化,變成路,而且剛好走過~ 歹徒想:蝦米輕功~明明是殺人利器~還好沒和他打起來~),還有牆(PS:說一聲,牆不能穿過,雖有輕功,但是還
是過不去牆,這個牆也是銀行的秘密~即使你是神犇也不行哦~ 楚楚:又坑我~)。(小明:路呢? 楚楚:廢話,當然有,隻不過這是銀行機密,
不能說!)
楚楚想在最短時間裏走出迷宮(小明:否則歹徒會發怒的,對不對? 楚楚:廢話!),若是超過了歹徒老大的忍耐時間time,那就……
(楚楚:小明……SOS,別忘了幫我報警!! 傳唿機:嘀,嘀,嘀…… 楚楚:咋麼可以這樣!可惡!)於是,他順便還要去找電話報個
警(報警不需要時間,打通即可。且電話機可能有多個,但也沒有可能沒有~)。
楚楚:我的預感告訴我,這個迷宮隻能向右或下走~鬱悶了~
輸入描述 Input Description
第1行是n,m, time,三個整數。
第2到n+1行每行有m個字母(有大寫也有小寫的)(楚楚:歹徒真笨~,就不能翻譯一下嗎~)。
字母解析:T(t)是陷阱,W(w)是牆,R(r)是路,A(a)是電話~ (遇到不認識的字符就~算之為路!)
輸出描述 Output Description
僅一行走出迷宮的最小時間t(走一步要一秒的說),不能在規定時間走出迷宮,或者打不了電話,請輸出“Oh my god!”(不包括引號)
。
樣例輸入 Sample Input
3 3 100
RRR
WWA
TRR
樣例輸出 Sample Output
4
//遞歸超時代碼 #include<stdio.h> #include<algorithm> using namespace std; char a[550][550]; int b[5000]; int endx,endy,phone,k=0,flag=0; void Found(int x,int y,int sum) { if(flag==1) return; if(a[x][y]=='W'||a[x][y]=='w') return; if(a[x][y]=='A'||a[x][y]=='a') phone=1;//這裏判斷不清晰 if(!(x==1&&y==1)) { if(a[x][y]=='T'||a[x][y]=='t') sum+=2; else sum++; } if(x==endx&&y==endy) {b[k++]=sum;flag=1;return;} if(y+1<=endy) Found(x,y+1,sum); if(x+1<=endx) Found(x+1,y,sum); if(y-1>=1) Found(x,y-1,sum); if(x-1>=1) Found(x-1,y,sum); } int main() { int i,j,n,m,time; scanf("%d%d%d",&n,&m,&time); getchar(); for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { scanf("%c",&a[i][j]); } if(i!=n) getchar(); } //若[1,1]或者[n,m]不是路,那麼就不能活著回去了 if((a[1][1]=='W'||a[1][1]=='w')||(a[n][m]=='W'||a[n][m]=='w')) printf("Oh my god!\n"); else { endx=n;endy=m;phone=0; Found(1,1,0); sort(b,b+k); if(b[0]<=time&&phone==1) printf("%d\n",b[0]); else printf("Oh my god!\n"); } return 0; }
AC代碼:
//動態規劃,由已知步數求未知步數 (參考,源代碼屬於“憶_碎碎念”) #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <vector> #include <cctype> #include <climits> using namespace std; #define BIGNUM 25000000 char str[505][505]; int dp[505][505]; int n, m, limit; bool phone = false; int main() { scanf("%d%d%d", &n, &m, &limit); for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) { scanf(" %c", &str[i][j]); str[i][j] = toupper(str[i][j]); } if(str[1][1] == 'W' || str[n][m] == 'W' || str[1][1] == 'T' || str[n][m] == 'T') { printf("Oh my god!"); exit(0); } else { for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) { if(i == 1 && j == 1)//起點不做計算 continue; dp[i][j] = BIGNUM;//賦值為很大的值,為了便於後麵計算步數 if(str[i][j] == 'W')//碰見牆就不做計算 ,直接返回 continue; if(str[i][j] == 'A') phone = true//有一次出現電話了就標記一下 //因為題設隻有兩種走法,向下或向右,那麼假如到了一個坐標,那麼隻能從左邊過來或者是從上邊過來 //隻要現在的遠遠大於原來的,就說明原來可能從那裏經過,所以本格加上次的時間再加一次這次的時間 //就是 dp[i][j] = dp[i - 1][j] + 1;或 dp[i][j] = dp[i][j - 1] + 1; //如果是陷阱就要多加一次 dp[i][j]++; if(i - 1 >= 1 && dp[i - 1][j] < dp[i][j]) dp[i][j] = dp[i - 1][j] + 1; if(j - 1 >= 1 && dp[i][j - 1] < dp[i][j]) dp[i][j] = dp[i][j - 1] + 1; if(str[i][j] == 'T') dp[i][j]++; } } } if(phone && dp[n][m] <= limit) printf("%d", dp[n][m]); else printf("Oh my god!"); return 0; }
最後更新:2017-04-03 12:55:26