閱讀233 返回首頁    go 阿裏雲 go 技術社區[雲棲]


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

  上一篇:go 數字讀取
  下一篇:go 異步圖片加載、內存、磁盤緩存