PKU 3083 Children of the Candy Corn 这题感触很多。。。。。。。。。。。。。。

  1. #include <stdio.h>
  2. #include <string.h>
  3. int right[4][2] = { {1,0},{0,1},{-1,0},{0,-1} };
  4. int left[4][2] = { {1,0},{0,-1},{-1,0},{0,1} };
  5. char map[45][45];
  6. int si, sj, ei, ej;
  7. int dir;
  8. int q[2500][2];
  9. int flag[45][45];
  10. int n, m;
  11. int dfs_left(int ni, int nj, int step)
  12. {
  13.     if ( ni==ei && nj==ej )
  14.         return step+1;
  15.     if ( ni<0 || ni>=n || nj<0 || nj>=m )
  16.         return 0;
  17.     if ( map[ni][nj]=='#' )
  18.         return 0;
  19.     dir = (dir+3)%4;
  20.     while ( 1 )
  21.     {
  22.         int tmp = dfs_left( ni+left[dir][0], nj+left[dir][1], step+1 );
  23.         if ( tmp>0 )
  24.             break;
  25.         dir = (dir+1)%4;
  26.     }
  27. }
  28. int dfs_right(int ni, int nj, int step)
  29. {
  30.     if ( ni==ei && nj==ej )
  31.         return step+1;
  32.     if ( ni<0 || ni>=n || nj<0 || nj>=m )
  33.         return 0;
  34.     if ( map[ni][nj]=='#' )
  35.         return 0;
  36.     dir = (dir+3)%4;
  37.     while ( 1 )
  38.     {
  39.         int tmp = dfs_right( ni+right[dir][0], nj+right[dir][1], step+1 );
  40.         if ( tmp>0 )
  41.             break;
  42.         dir = (dir+1)%4;
  43.     }
  44. }
  45. int bfs()
  46. {
  47.     memset( flag, 0, sizeof(flag) );
  48.     int head = 0;
  49.     int tail = 0;
  50.     q[tail][0] = si;
  51.     q[tail++][1] = sj;
  52.     flag[si][sj] = 1;
  53.     int step = 0;
  54.     while ( head<tail && flag[ei][ej]==0 )
  55.     {
  56.         int tmp = tail;
  57.         step++;
  58.         while ( head<tmp && flag[ei][ej]==0 )
  59.         {
  60.             int ni = q[head][0];
  61.             int nj = q[head++][1];
  62.             for ( int i=0; i<4; i++ )
  63.             {
  64.                 int ti = ni+left[i][0];
  65.                 int tj = nj+left[i][1];
  66.                 if ( ti>=0 && ti<n && tj>=0 && tj<m && flag[ti][tj]==0
  67.                     && map[ti][tj]!='#' )
  68.                 {
  69.                     q[tail][0] = ti;
  70.                     q[tail++][1] = tj;
  71.                     flag[ti][tj] = 1;
  72.                 }
  73.             }
  74.         }
  75.     }
  76.     return step+1;
  77. }
  78. int main ()
  79. {
  80.     int t;
  81.     scanf("%d", &t );
  82.     while ( t-- )
  83.     {
  84.         scanf("%d %d", &m, &n );
  85.         for ( int i=0; i<n; i++ )
  86.         {
  87.             scanf("%s", map[i] );
  88.             for ( int j=0; j<m; j++ )
  89.             {
  90.                 if ( map[i][j] =='S' )
  91.                     si = i, sj=j;
  92.                 if ( map[i][j] =='E' )
  93.                     ei = i, ej= j;
  94.             }
  95.         }
  96.         dir = 0;
  97.         printf("%d %d %d/n", dfs_left(si,sj,0), dfs_right(si,sj,0), bfs() );
  98.     }
  99.     return 0;
  100. }

上面的代码不是我写的是网上搜到的。。。这个题目最优结果不难关键是向左和向右。。。看到讨论里有人写了12K多自己也是写了一晚上码了好多。。向左向右其实也没什么难度只是要写的非常多属于那种硬扯的话是一定扯的出来的题目。。。。于是写着越多越觉的无意义(代码之美里有句话说的好大概记的是说对于厄长的代码要毫不客气的咔嚓掉)。。于是一怒之下全删光了。。。。。。。。。。接着就发现了上面这个代码。。。实在佩服写这个人。。。。说实在的我没看懂。。。。。。。先存着吧。。还要谢谢这位兄弟恩抱歉我拿你的代码AC了=V=。。。。。。。。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值