HDU 2612 Find a way

http://acm.hdu.edu.cn/showproblem.php?pid=2612

题意 : Y和M去同一个KFC的时间最短(KFC可能有多个)

我的方法是从KFC开始搜索到两个人的最短时间之和。唯一蛋疼的是一开始TLE了几把。伤啊。



/*
*     Danceonly
*/

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>

using namespace std;
typedef long long LL;

#define MAX(a,b) (a > b ? a : b)
#define MIN(a,b) (a < b ? a : b)

const int maxn = 10000007;
struct node
{
      int x;
      int y;
}kfc[100005];
struct abc
{
      int x,y;
      int step;
}q[100005],e;
int maze[205][205],vis[205][205];
int dir[4][2] = {1,0,0,1,-1,0,0,-1};
int N,M;
int BFS(int sx,int sy,int A)
{
      int tail,head,step,x,y;
      head = tail = 0;
      q[head].x = sx;
      q[head].y = sy;
      q[head].step = 0;
      vis[sx][sy] = 1;
      while (head <= tail)
      {
            x = q[head].x;
            y = q[head].y;
            step = q[head].step;
            for (int i=0;i<4;i++)
            {
                  e.x = x + dir[i][0];
                  e.y = y + dir[i][1];
                  if (maze[e.x][e.y] ==  0 || vis[e.x][e.y])continue ;
                  e.step = step + 1;
                  vis[e.x][e.y] = 1;
                  if (maze[e.x][e.y] ==  A)
                  {
                        return e.step;
                  }
                  q[++tail] = e;
            }
            head++;
      }
      return maxn;
}
void show()
{
      for (int i=1;i<=N;i++)
      {
            for (int j=1;j<=M;j++)
                  printf("%d ",maze[i][j]);
            printf("\n");
      }
}
void init()
{
      memset(vis,0,sizeof(vis));
      memset(maze,0,sizeof(maze));
      return ;
}
int main()
{
      while (scanf("%d%d",&N,&M) == 2)
      {
            int Yx,Yy,Mx,My;
            memset(maze,0,sizeof(maze));
            int c = 0;
            for (int i=1;i<=N;i++)
            {
                  char ss[1005];
                  scanf("%s",ss);
                  for (int j=0;j<M;j++)
                        if (ss[j] == '.')maze[i][j+1] = 1;
                        else if (ss[j] == '@'){kfc[c].x = i;kfc[c++].y = j + 1;maze[i][j+1] = 1;}
                        else if (ss[j] == 'Y'){maze[i][j+1] = 2;Yx = i;Yy = j + 1;}
                        else if (ss[j] == 'M'){maze[i][j+1] = 3;Mx = i;My = j + 1;}
            }
            //show();
            int ans = maxn;
            for (int i=0;i<c;i++)
            {
                  int sum = 0;
                  memset(vis,0,sizeof(vis));
                  sum += BFS(kfc[i].x,kfc[i].y,2);
                  if (sum + abs(kfc[i].x - Mx) + abs(kfc[i].y-My) >= ans)
                        continue ;
                  memset(vis,0,sizeof(vis));
                  sum += BFS(kfc[i].x,kfc[i].y,3);
                  if (ans > sum)ans = sum;
            }
            printf("%d\n",ans * 11);
      }
      return 0;
}

/*
4 4
Y.#@
....
.#..
@..M
4 4
Y.#@
....
.#..
@#.M
5 5
Y..@.
.#...
.#...
@..M.
#...#
*/


转载于:https://www.cnblogs.com/cnwsycf/p/3335376.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值