liangpeiqi0

ni解题报告

 

题目大意:

贝茜需要通过一个被Ni的骑士守卫的树林。贝茜必须尽可能快的找到一个灌木并且给骑士带去。贝茜有树林的地图,地图大小是W*H(1〈=W〈=1000;1〈=H〈=1000)。贝茜只可以沿着四个方向走:北,东,南,或者西(不能对角)。她从一个格子走到相邻的格子需要花费1天时间。保证贝茜可以拿到一个灌木然后交给Ni的骑士。求确定最快的路线。

地图上的整数描述:

0:贝茜可以通过;

1:贝茜不可以通过;

2:贝茜开始的位置;

3:Ni的骑士位置;

4:灌木的位置;

输入样例:

8 4

4 1 0 0 0 0 1 0

0 0 0 1 0 1 0 0

0 2 1 1 3 0 4 0

0 0 0 4 1 1 1 0

输出样例:

11

样例解释:N, W, N, S, E, E, N, E, E, S, S

解题思路:

    这道题明显就是麻烦的宽度搜索啦。(实在是太麻烦了o(>﹏<)o)首先求贝茜到各个灌木的距离,然后就求Ni的骑士到各个灌木的距离,两者相加就是符合题目的路线,求个最小值,输出,搞定!(看上去好像很简单,其实不然!!!)

参考程序:

# include <iostream>
# include <stdio.h>

using namespace std;
const int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
int n,m,a[1005][1005],s[1005][1005];
bool f[1005][1005],f2[1005][1005];
struct data
{
 int x,y,t;
}open[1000*1000+100];

void bfs(int x,int y)
{
 int h=1,t=1;
 open[1].x=x; open[1].y=y; open[1].t=0;
 for (;h<=t;h++)
    {
     for (int i=0; i<4; i++)
     {
      int nx=open[h].x+dx[i],ny=open[h].y+dy[i];

      if (nx<0 || ny<0 || nx>=n || ny>=m || !f[nx][ny]) continue;
      f[nx][ny]=false;
    if (a[nx][ny]==4)

{
       s[nx][ny]=open[h].t+1;
     continue;
    }
      t++; open[t].x=nx; open[t].y=ny; open[t].t=open[h].t+1;
     }
    }
} // 宽度搜索出贝茜到各个灌木的距离

int main()
{
 int mx[3000],my[3000];
 int sx,sy,fx,fy;
 cin>>m>>n;
 for (int i=0; i<n; i++)
 for (int j=0; j<m; j++)
 {
  int c;
  cin>>a[i][j];
  f[i][j]=f2[i][j]=true;
  if (a[i][j]==1) f[i][j]=f2[i][j]=false;
  else if (a[i][j]==2) { sx=i; sy=j; }
  else if (a[i][j]==3) { fx=i; fy=j; }
  s[i][j]=0x7ffffff;
 }
 int ans=0x7fffff;
 bfs(sx,sy);
 int h=1,t=1;
 open[1].x=fx; open[1].y=fy; open[1].t=0;
 for (;h<=t;h++)
    {
     for (int i=0; i<4; i++)
     {
      int nx=open[h].x+dx[i],ny=open[h].y+dy[i];
      if (a[nx][ny]==4) { ans=min(ans,s[nx][ny]+open[h].t+1); continue; }
      if (nx<0 || ny<0 || nx>=n || ny>=m || !f2[nx][ny]) continue;
      f2[nx][ny]=false;
      t++; open[t].x=nx; open[t].y=ny; open[t].t=open[h].t+1;
     }
    } // 求Ni的骑士到各个灌木的距离
 cout<<ans<<endl;
 return 0;
}

上一篇 下一篇
评论
©liangpeiqi0 | Powered by LOFTER